如何从 Cookies/Session 更改 dbContext 数据库名称

How to change dbContext database name from Cookies/Session

我有多个用户使用他们自己的数据库相同的模式,因此我们将他们的 ConnectionString 存储在 cookie/session 中可用的解决方案。

如何使用 HttpContext。 Cookies/Session 要按请求更改 DBContext 的连接字符串的数据?

DB Context

public MyContext(string ConnectionString) : base(ConnectionString)
{

}

DependencyRegistrar

  public virtual void Register(ContainerBuilder builder, ITypeFinder typeFinder)
    {
    //data layer
        var dataSettingsManager = new DataSettingsManager();
        var dataProviderSettings = dataSettingsManager.LoadSettings();
        builder.Register(c => dataSettingsManager.LoadSettings()).As<DataSettings>();
        builder.Register(x => new EfDataProviderManager(x.Resolve<DataSettings>())).As<BaseDataProviderManager>().InstancePerDependency();

        builder.Register(x => x.Resolve<BaseDataProviderManager>().LoadDataProvider()).As<IDataProvider>().InstancePerDependency();

        if (dataProviderSettings != null && dataProviderSettings.IsValid())
        {
            var efDataProviderManager = new EfDataProviderManager(dataSettingsManager.LoadSettings());
            var dataProvider = efDataProviderManager.LoadDataProvider();
            dataProvider.InitConnectionFactory();

            builder.Register<IDbContext>(c => new DBObjectContext(dataProviderSettings.DataConnectionString)).InstancePerLifetimeScope();
        }
        else
            builder.Register<IDbContext>(c => new DBObjectContext(dataSettingsManager.LoadSettings().DataConnectionString)).InstancePerLifetimeScope();

        //repositories
        builder.RegisterGeneric(typeof(EfRepository<>)).As(typeof(IRepository<>)).InstancePerLifetimeScope();

你应该可以替换:

从这里开始: dataProviderSettings.DataConnectionString

builder.Register<IDbContext>(c => new DBObjectContext(dataProviderSettings.DataConnectionString)).InstancePerLifetimeScope();

使用 class 将从 cookie 中读取值。

新的 class 显然不是控制器,因此需要通过以下方式访问 HttpContextIHttpContextAccessor.

为此请添加以下内容:

public void ConfigureServices(IServiceCollection services)
{
     //other registrations
     services.AddHttpContextAccessor();
}

然后在你的新 class:

    public class ConnectionStringAccessor {
        private IHttpContextAccessor _httpContextAccessor;
        public ConnectionStringAccessor(IHttpContextAccessor httpContextAccessor)
        {
            _httpContextAccessor = httpContextAccessor;
        }

        public string GetConnectionString() {
            return  _httpContextAccessor.HttpContext.Request.Cookies["cookieName"].Value;
//you can consider some encryption/decryption or whatever you need to.
        }
    }

然后最后:

builder.Register<IDbContext>(c => new DBObjectContext(c.Resolve<ConnectionStringAccessor >().GetConnecionString()).InstancePerLifetimeScope();

我目前没有可用的 VisualStudio,所以我在没有构建或测试的情况下放置了代码。此外,您的新 class 必须在 DI 中注册。

更多信息请参考这篇文章:https://docs.microsoft.com/en-us/aspnet/core/fundamentals/http-context?view=aspnetcore-2.2

正如我在评论中所说,只是为了强调,处理连接字符串等敏感事物的方式非常不安全。