public void GetConnectionString_throws_when_cant_find_named_connection_in_config()
 {
     var config = new AppConfig(CreateEmptyConfig());
     var info = new DbConnectionInfo("FindMe");
     Assert.Equal(Strings.DbConnectionInfo_ConnectionStringNotFound("FindMe"),
                  Assert.Throws<InvalidOperationException>(() => info.GetConnectionString(config)).Message);
 }
        public virtual Type TryLoadFromConfig(AppConfig config)
        {
            DebugCheck.NotNull(config);

            var typeName = config.ConfigurationTypeName;
            if (string.IsNullOrWhiteSpace(typeName))
            {
                return null;
            }

            Type type;
            try
            {
                type = Type.GetType(typeName, throwOnError: true);
            }
            catch (Exception ex)
            {
                throw new InvalidOperationException(Strings.DbConfigurationTypeNotFound(typeName), ex);
            }

            if (!typeof(DbConfiguration).IsAssignableFrom(type))
            {
                throw new InvalidOperationException(
                    Strings.CreateInstance_BadDbConfigurationType(type.ToString(), typeof(DbConfiguration).ToString()));
            }

            return type;
        }
        public void Can_find_named_connection_in_config()
        {
            var config = new AppConfig(CreateEmptyConfig().AddConnectionString("FindMe", "connection_string", "provider_invariant_name"));
            var info = new DbConnectionInfo("FindMe");
            var connection = info.GetConnectionString(config);

            Assert.Equal("FindMe", connection.Name);
            Assert.Equal("connection_string", connection.ConnectionString);
            Assert.Equal("provider_invariant_name", connection.ProviderName);
        }
        public void Returns_valid_connection_from_string_and_provider()
        {
            var config = new AppConfig(CreateEmptyConfig());
            var info = new DbConnectionInfo("connection_string", "provider_invariant_name");
            var connection = info.GetConnectionString(config);

            Assert.Null(connection.Name);
            Assert.Equal("connection_string", connection.ConnectionString);
            Assert.Equal("provider_invariant_name", connection.ProviderName);
        }
        public AppConfigDependencyResolver(
            AppConfig appConfig,
            InternalConfiguration internalConfiguration,
            ProviderServicesFactory providerServicesFactory = null)
        {
            DebugCheck.NotNull(appConfig);

            _appConfig = appConfig;
            _internalConfiguration = internalConfiguration;
            _providerServicesFactory = providerServicesFactory ?? new ProviderServicesFactory();
        }
        // <summary>
        // Gets the connection information represented by this instance.
        // </summary>
        // <param name="config"> Configuration to use if connection comes from the configuration file. </param>
        internal ConnectionStringSettings GetConnectionString(AppConfig config)
        {
            DebugCheck.NotNull(config);

            if (_connectionName != null)
            {
                var result = config.GetConnectionString(_connectionName);
                if (result == null)
                {
                    throw Error.DbConnectionInfo_ConnectionStringNotFound(_connectionName);
                }

                return result;
            }

            return new ConnectionStringSettings(null, _connectionString, _providerInvariantName);
        }
        /// <summary>
        ///     Gets the connection information represented by this instance.
        /// </summary>
        /// <param name = "config">Configuration to use if connection comes from the configuration file.</param>
        internal ConnectionStringSettings GetConnectionString(AppConfig config)
        {
            //Contract.Requires(config != null);

            if (_connectionName != null)
            {
                var result = config.GetConnectionString(_connectionName);
                if (result == null)
                {
                    throw Error.DbConnectionInfo_ConnectionStringNotFound(_connectionName);
                }

                return result;
            }

            return new ConnectionStringSettings(null, _connectionString, _providerInvariantName);
        }
        public virtual InternalConfiguration TryLoadFromConfig(AppConfig config)
        {
            DebugCheck.NotNull(config);

            var typeName = config.ConfigurationTypeName;
            if (string.IsNullOrWhiteSpace(typeName))
            {
                return null;
            }

            Type configType;
            try
            {
                configType = Type.GetType(typeName, throwOnError: true);
            }
            catch (Exception ex)
            {
                throw new InvalidOperationException(Strings.DbConfigurationTypeNotFound(typeName), ex);
            }

            return configType.CreateInstance<DbConfiguration>(Strings.CreateInstance_BadDbConfigurationType).InternalConfiguration;
        }
            public void PopConfiguration_removes_the_first_configuration_associated_with_the_given_AppConfig()
            {
                var manager = CreateManager();
                var configuration = new Mock<DbConfiguration>().Object;
                var appConfig1 = AppConfig.DefaultInstance;
                var appConfig2 = new AppConfig(ConfigurationManager.ConnectionStrings);

                manager.SetConfiguration(configuration);

                manager.PushConfiguration(appConfig1, typeof(DbContext));
                var pushed1 = manager.GetConfiguration();
                manager.PushConfiguration(appConfig2, typeof(DbContext));

                manager.PopConfiguration(appConfig2);
                Assert.Same(pushed1, manager.GetConfiguration());

                manager.PopConfiguration(appConfig1);
                Assert.Same(configuration, manager.GetConfiguration());
            }
            public void Configurations_can_be_pushed_and_popped_from_multiple_threads_concurrently()
            {
                for (var i = 0; i < 30; i++)
                {
                    var manager = new DbConfigurationManager(new DbConfigurationLoader(), new DbConfigurationFinder());
                    var config = manager.GetConfiguration();

                    ExecuteInParallel(
                        () =>
                            {
                                var appConfig = new AppConfig(new ConnectionStringSettingsCollection());
                                manager.PushConfiguration(appConfig, typeof(SimpleModelContext));
                                manager.PopConfiguration(appConfig);
                            });

                    Assert.Same(config, manager.GetConfiguration());
                }
            }
 public virtual DbConfiguration TryLoadFromConfig(AppConfig config)
 {
     // TODO: Implement loading from app.config
     return null;
 }
        public virtual bool AppConfigContainsDbConfigurationType(AppConfig config)
        {
            DebugCheck.NotNull(config);

            return !string.IsNullOrWhiteSpace(config.ConfigurationTypeName);
        }
        public void GetService_can_be_accessed_from_multiple_threads_concurrently()
        {
            var appConfig = new AppConfig(
                CreateEmptyConfig().AddDefaultConnectionFactory(typeof(FakeConnectionFactory).AssemblyQualifiedName));

            for (var i = 0; i < 30; i++)
            {
                var bag = new ConcurrentBag<IDbConnectionFactory>();
                var resolver = new AppConfigDependencyResolver(appConfig);

                ExecuteInParallel(() => bag.Add(resolver.GetService<IDbConnectionFactory>()));
                
                Assert.Equal(20, bag.Count);
                Assert.True(bag.All(c => resolver.GetService<IDbConnectionFactory>() == c));
            }
        }
        public virtual void PopConfiguration(AppConfig config)
        {
            DebugCheck.NotNull(config);

            lock (_lock)
            {
                var configuration = _configurationOverrides.Value.FirstOrDefault(c => c.Item1 == config);
                if (configuration != null)
                {
                    _configurationOverrides.Value.Remove(configuration);
                }
            }
        }
Beispiel #15
0
            public void PopConfiguration_removes_the_first_configuration_associated_with_the_given_AppConfig()
            {
                var manager = CreateManager();
                var mockInternalConfiguration = new Mock<InternalConfiguration>(null, null, null, null)
                    {
                        CallBase = true
                    };

                var mockDbConfiguration = new Mock<DbConfiguration>();
                mockDbConfiguration.Setup(m => m.InternalConfiguration).Returns(mockInternalConfiguration.Object);
                mockInternalConfiguration.Setup(m => m.Owner).Returns(mockDbConfiguration.Object);

                var appConfig1 = AppConfig.DefaultInstance;
                var appConfig2 = new AppConfig(ConfigurationManager.ConnectionStrings);

                manager.SetConfiguration(mockInternalConfiguration.Object);

                manager.PushConfiguration(appConfig1, typeof(DbContext));
                var pushed1 = manager.GetConfiguration();
                manager.PushConfiguration(appConfig2, typeof(DbContext));

                manager.PopConfiguration(appConfig2);
                Assert.Same(pushed1, manager.GetConfiguration());

                manager.PopConfiguration(appConfig1);
                Assert.Same(mockInternalConfiguration.Object, manager.GetConfiguration());
            }
Beispiel #16
0
            public void PushConfugiration_switches_in_original_root_resolver()
            {
                var appConfig = new AppConfig(new ConnectionStringSettingsCollection());
                var mockLoader = new Mock<DbConfigurationLoader>();
                mockLoader.Setup(m => m.TryLoadFromConfig(appConfig)).Returns(typeof(DbConfigurationWithMockInternals));
                mockLoader.Setup(m => m.AppConfigContainsDbConfigurationType(It.IsAny<AppConfig>())).Returns(true);

                var manager = CreateManager(mockLoader);
                var defaultConfiguration = manager.GetConfiguration();

                manager.PushConfiguration(appConfig, typeof(DbContext));

                Mock.Get(manager.GetConfiguration()).Verify(m => m.SwitchInRootResolver(defaultConfiguration.RootResolver));
            }
Beispiel #17
0
            public void AppConfigResolver_is_added_to_pushed_configuration()
            {
                var appConfig = new AppConfig(new ConnectionStringSettingsCollection());
                var mockLoader = new Mock<DbConfigurationLoader>();
                mockLoader.Setup(m => m.TryLoadFromConfig(appConfig)).Returns(typeof(DbConfigurationWithMockInternals));
                mockLoader.Setup(m => m.AppConfigContainsDbConfigurationType(It.IsAny<AppConfig>())).Returns(true);
                var manager = CreateManager(mockLoader);

                manager.PushConfiguration(appConfig, typeof(DbContext));

                Mock.Get(manager.GetConfiguration()).Verify(m => m.AddAppConfigResolver(It.IsAny<AppConfigDependencyResolver>()));
            }
Beispiel #18
0
            public void PushConfugiration_pushes_default_configuration_if_no_other_found()
            {
                var mockLoader = new Mock<DbConfigurationLoader>();
                var mockFinder = new Mock<DbConfigurationFinder>();

                var manager = CreateManager(mockLoader, mockFinder);

                var defaultConfiguration = manager.GetConfiguration();

                var appConfig = new AppConfig(new ConnectionStringSettingsCollection());
                manager.PushConfiguration(appConfig, typeof(DbContext));

                Assert.NotSame(defaultConfiguration, manager.GetConfiguration());
                mockLoader.Verify(m => m.TryLoadFromConfig(appConfig));
                mockFinder.Verify(m => m.TryFindConfigurationType(typeof(DbContext), It.IsAny<IEnumerable<Type>>()));
            }
Beispiel #19
0
            public void PushConfugiration_pushes_and_locks_configuration_discovered_in_context_assembly_if_found()
            {
                var mockLoader = new Mock<DbConfigurationLoader>();
                var mockFinder = new Mock<DbConfigurationFinder>();
                mockFinder.Setup(m => m.TryFindConfigurationType(typeof(DbContext), It.IsAny<IEnumerable<Type>>())).Returns(
                    typeof(FakeConfiguration));

                var manager = CreateManager(mockLoader, mockFinder);

                var appConfig = new AppConfig(new ConnectionStringSettingsCollection());
                manager.PushConfiguration(appConfig, typeof(DbContext));

                Assert.IsType<FakeConfiguration>(manager.GetConfiguration().Owner);
                AssertIsLocked(manager.GetConfiguration());
                mockLoader.Verify(m => m.TryLoadFromConfig(appConfig));
                mockFinder.Verify(m => m.TryFindConfigurationType(typeof(DbContext), It.IsAny<IEnumerable<Type>>()));
            }
        public virtual void PushConfiguration(AppConfig config, Type contextType)
        {
            Contract.Requires(config != null);
            Contract.Requires(contextType != null);
            Contract.Requires(typeof(DbContext).IsAssignableFrom(contextType));

            var configuration = _loader.TryLoadFromConfig(config)
                                ?? _finder.TryCreateConfiguration(contextType.Assembly.GetAccessibleTypes())
                                ?? new DbConfiguration();

            configuration.AddAppConfigResolver(new AppConfigDependencyResolver(config));

            configuration.Lock();
            _configurationOverrides.Add(Tuple.Create(config, configuration));
        }
        public virtual void PopConfiguration(AppConfig config)
        {
            Contract.Requires(config != null);

            var configuration = _configurationOverrides.FirstOrDefault(c => c.Item1 == config);
            if (configuration != null)
            {
                _configurationOverrides.Remove(configuration);
            }
        }
        public virtual bool PushConfiguration(AppConfig config, Type contextType)
        {
            DebugCheck.NotNull(config);
            DebugCheck.NotNull(contextType);
            Debug.Assert(typeof(DbContext).IsAssignableFrom(contextType));

            // Perf optimization: if there is no change to the default app-domain config and if the
            // context assembly has already been checked for configurations, then avoid creating
            // and pushing a new configuration since it would be the same as the current one anyway.
            if (config == AppConfig.DefaultInstance
                && (contextType == typeof(DbContext) || _knownAssemblies.ContainsKey(contextType.Assembly)))
            {
                return false;
            }

            var configuration = (_loader.TryLoadFromConfig(config)
                                 ?? _finder.TryFindConfigurationType(contextType)
                                 ?? typeof(DbConfiguration))
                .CreateInstance<DbConfiguration>(Strings.CreateInstance_BadDbConfigurationType)
                .InternalConfiguration;

            configuration.SwitchInRootResolver(_configuration.Value.RootResolver);
            configuration.AddAppConfigResolver(new AppConfigDependencyResolver(config, configuration));

            lock (_lock)
            {
                _configurationOverrides.Value.Add(Tuple.Create(config, configuration));
            }

            configuration.Lock();

            return true;
        }
        public AppConfigDependencyResolver(AppConfig appConfig)
        {
            //Contract.Requires(appConfig != null);

            _appConfig = appConfig;
        }
        private bool TryInitializeFromAppConfig(string name, AppConfig config)
        {
            DebugCheck.NotNull(config);

            var appConfigConnection = FindConnectionInConfig(name, config);
            if (appConfigConnection != null)
            {
                InitializeFromConnectionStringSetting(appConfigConnection);
                _connectionStringOrigin = DbConnectionStringOrigin.Configuration;
                _connectionStringName = appConfigConnection.Name;

                return true;
            }

            return false;
        }
Beispiel #25
0
        private DbContextInfo(
            Type contextType,
            DbProviderInfo modelProviderInfo,
            AppConfig config,
            DbConnectionInfo connectionInfo,
            Func<IDbDependencyResolver> resolver = null)
        {
            if (!typeof(DbContext).IsAssignableFrom(contextType))
            {
                throw new ArgumentOutOfRangeException("contextType");
            }

            _resolver = resolver ?? (() => DbConfiguration.DependencyResolver);

            _contextType = contextType;
            _modelProviderInfo = modelProviderInfo;
            _appConfig = config;
            _connectionInfo = connectionInfo;

            _activator = CreateActivator();

            if (_activator != null)
            {
                var context = CreateInstance();

                if (context != null)
                {
                    _isConstructible = true;

                    using (context)
                    {
                        _connectionString = 
                            DbInterception.Dispatch.Connection.GetConnectionString(
                            context.InternalContext.Connection,
                            new DbInterceptionContext().WithDbContext(context));
                        _connectionStringName = context.InternalContext.ConnectionStringName;
                        _connectionProviderName = context.InternalContext.ProviderName;
                        _connectionStringOrigin = context.InternalContext.ConnectionStringOrigin;
                    }
                }
            }
        }
Beispiel #26
0
        // <summary>
        // Called internally when a context info is needed for an existing context, which may not be constructable.
        // </summary>
        // <param name="context"> The context instance to get info from. </param>
        internal DbContextInfo(DbContext context, Func<IDbDependencyResolver> resolver = null)
        {
            Check.NotNull(context, "context");

            _resolver = resolver ?? (() => DbConfiguration.DependencyResolver);

            _contextType = context.GetType();
            _appConfig = AppConfig.DefaultInstance;

            var internalContext = context.InternalContext;
            _connectionProviderName = internalContext.ProviderName;

            _connectionInfo = new DbConnectionInfo(internalContext.OriginalConnectionString, _connectionProviderName);

            _connectionString = internalContext.OriginalConnectionString;
            _connectionStringName = internalContext.ConnectionStringName;
            _connectionStringOrigin = internalContext.ConnectionStringOrigin;
        }
Beispiel #27
0
        private DbContextInfo(
            Type contextType,
            DbProviderInfo modelProviderInfo,
            AppConfig config,
            DbConnectionInfo connectionInfo)
        {
            if (!typeof(DbContext).IsAssignableFrom(contextType))
            {
                throw new ArgumentOutOfRangeException("contextType");
            }

            _contextType = contextType;
            _modelProviderInfo = modelProviderInfo;
            _appConfig = config;
            _connectionInfo = connectionInfo;

            _activator = CreateActivator();

            if (_activator != null)
            {
                var context = _activator();

                if (context != null)
                {
                    _isConstructible = true;

                    PushConfiguration(context);

                    using (context)
                    {
                        ConfigureContext(context);

                        _connectionString = context.InternalContext.Connection.ConnectionString;
                        _connectionStringName = context.InternalContext.ConnectionStringName;
                        _connectionProviderName = context.InternalContext.ProviderName;
                        _connectionStringOrigin = context.InternalContext.ConnectionStringOrigin;
                    }
                }
            }
        }
        public virtual bool AppConfigContainsDbConfigurationType(AppConfig config)
        {
            Contract.Requires(config != null);

            return !string.IsNullOrWhiteSpace(config.ConfigurationTypeName);
        }
        /// <summary>
        ///     Attempts to locate a connection entry in the configuration based on the supplied context name.
        /// </summary>
        /// <param name="name"> The name to search for. </param>
        /// <param name="config"> The configuration to search in. </param>
        /// <returns> Connection string if found, otherwise null. </returns>
        private static ConnectionStringSettings FindConnectionInConfig(string name, AppConfig config)
        {
            // Build a list of candidate names that might be found in the app.config/web.config file.
            // The first entry is the full name.
            var candidates = new List<string>
                {
                    name
                };

            // Second entry is full name with namespace stripped out.
            var lastDot = name.LastIndexOf('.');
            if (lastDot >= 0
                && lastDot + 1 < name.Length)
            {
                candidates.Add(name.Substring(lastDot + 1));
            }

            // Now go through each candidate.  As soon as we find one that matches, stop.
            var appConfigConnection = (from c in candidates
                                       where config.GetConnectionString(c) != null
                                       select config.GetConnectionString(c)).FirstOrDefault();
            return appConfigConnection;
        }
Beispiel #30
0
        /// <summary>
        ///     Called internally when a context info is needed for an existing context, which may not be constructable.
        /// </summary>
        /// <param name="context"> The context instance to get info from. </param>
        internal DbContextInfo(DbContext context)
        {
            Check.NotNull(context, "context");

            _contextType = context.GetType();
            _appConfig = AppConfig.DefaultInstance;

            var internalContext = context.InternalContext;
            _connectionProviderName = internalContext.ProviderName;

            _connectionInfo = new DbConnectionInfo(internalContext.OriginalConnectionString, _connectionProviderName);

            _connectionString = internalContext.OriginalConnectionString;
            _connectionStringName = internalContext.ConnectionStringName;
            _connectionStringOrigin = internalContext.ConnectionStringOrigin;
        }