如何从 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 显然不是控制器,因此需要通过以下方式访问 HttpContext
:IHttpContextAccessor
.
为此请添加以下内容:
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
正如我在评论中所说,只是为了强调,处理连接字符串等敏感事物的方式非常不安全。
我有多个用户使用他们自己的数据库相同的模式,因此我们将他们的 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 显然不是控制器,因此需要通过以下方式访问 HttpContext
:IHttpContextAccessor
.
为此请添加以下内容:
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
正如我在评论中所说,只是为了强调,处理连接字符串等敏感事物的方式非常不安全。