我们正在为我们的应用程序使用每个租户逻辑数据库。 我们目前需要根据当前登录的用户动态构建连接字符串。
我们真的想将租户数据库上下文用作服务(DI)。但是,dbcontext初始化在configure services方法中完成,IHttpContextAccessor在此阶段为null。
有没有办法调用services.addDbContext但是通知他等到IHttpContextAccessor被实例化?或者我真的需要每次都实例一下?
谢谢!
这是我的一些代码:
var sp = services.BuildServiceProvider();
services.AddDbContext<ESDataContext>(options => options.UseSqlServer(new DataConnectionAPI(sp.GetService<IHttpContextAccessor>(),sp.GetService<ESUsersContext>()).DataConnectionString(), ma => ma.MigrationsAssembly("ESData")));
答案 0 :(得分:2)
我建议不要使用AddDbContext,而是自己注册服务。 这样的事情:
services
.AddScoped<ESDataContext>()
.AddScoped(sp =>
new DbContextOptionsBuilder<ESDataContext>()
.UseSqlServer(
new DataConnectionAPI(
sp.GetService<IHttpContextAccessor>(),
sp.GetService<ESUsersContext>()
).DataConnectionString())
.Options)
您可以构建服务提供商。
答案 1 :(得分:0)
我建议注册一个在运行时修改连接字符串的工厂并返回上下文实例。 IHttpContextAccessor
仅在http请求期间可用于访问用户信息所需的所有信息,因为必须首先执行授权过滤器。
https://docs.microsoft.com/en-us/aspnet/core/mvc/controllers/filters
修改强>
您不会在configureservice方法中注册db-context。
您将在DbContext中创建一个带DbContextOptions(基础构造函数)的构造函数。您将创建一个注入HttpContextAccesor和任何必要的DbContextFactory,然后在运行时注入此工厂以手动创建DbContext并返回值。
然后注册工厂
services.AddScoped<IDbContextFactory, DbContextFactory();
注意:为此目的不要实施IDesignTimeDbContextFactory,这应仅用于创建迁移。