EF在相同类型的不同上下文之间切换

时间:2013-12-10 15:13:08

标签: c# entity-framework inversion-of-control autofac

我有一个多应用程序,它有多个数据库,供不同客户使用相同的数据库结构。

在应用程序中,用户根据其客户ID登录后,我将知道其客户数据库的连接字符串,并在登录按钮单击事件后,我将需要动态更改我的数据库上下文。

我正在使用EF 5.0和Autofac IOC容器。 我在这里粘贴了我的代码,这对我没有帮助。

我能以最好的方式管理这个吗?

        string EntityFrameworkConnectionString = null;
        var builder = new ContainerBuilder();

        builder.Register(c =>
        {
            if (string.IsNullOrEmpty(EntityFrameworkConnectionString))
            {
                var profileProvider = c.Resolve<IConfigurationProfileProvider<CustomerProfile>>();
                var profile = profileProvider.GetProfile();
                EntityFrameworkConnectionString = profile.CustomerDatabaseConnectionString;
            }
            return new CustomerDataContext(EntityFrameworkConnectionString);
        })
        .As<ICustomerDataContext>()
        .As<IDbContext>()
        .InstancePerDependency();

        builder.RegisterType<CustomerDataContextFactory>().As<ICustomerDataContextFactory>();

        var assembly = Assembly.GetExecutingAssembly();
        builder.RegisterAssemblyTypes(assembly)
               .Where(t => t.Name.EndsWith("Repository"))
               .AsImplementedInterfaces()
               .InstancePerDependency();

2 个答案:

答案 0 :(得分:1)

我会这样做:

  1. 引入一个将管理连接字符串的接口:

    public interface IConnectionStringManager
    {
        string GetConnectionString();
    }  
    
  2. 将IConfigurationProfileProvider注入其中的实现:

    public class ConnectionStringManager : IConnectionStringManager
    {
        private readonly IConfigurationProfileProvider<CustomerProfile> _configurationProfileProvider;
    
        public ConnectionStringManager(IConfigurationProfileProvider<CustomerProfile> configurationProfileProvider)
        {
            _configurationProfileProvider = configurationProfileProvider;
        }
    
        public string GetConnectionString()
        {
            return _configurationProfileProvider.GetProfile().CustomerDatabaseConnectionString;
        }
    }  
    
  3. 然后将IConnectionStringManager注入CustomerDataContext并获取连接字符串。

    public CustomerDataContext(IConnectionStringManager connectionStringManager)
    {
        var connectionString = connectionStringManager.GetConnectionString();
        // pass the connectionString to your context
    }
    
  4. 像往常一样注册ConnectionStringManager和CustomerDataContext:

    builder.RegisterType<ConnectionStringManager>().As<IConnectionStringManager>();
    builder.RegisterType<CustomerDataContext>()
        .As<ICustomerDataContext>()
        .As<IDbContext>()
        .InstancePerDependency();
    
  5. 顺便说一句,看看Autofac Multitenant Integration可以缓解多租户支持。

答案 1 :(得分:0)

我真的认为你不需要在这种情况下使用你的IOC(特别是考虑到你做了多么复杂)。为什么不直接将该连接字符串存储为静态变量,然后覆盖DbContext的构造函数以始终使用该变量?

像这样:

对于连接字符串:

public static class StaticVariables
{
  public static string ConnectionString { get; set; }
}

对于DbContext构造函数:

public DbContext()
{
  this(StaticVariables.ConnectionString);
}