等待IHttpContextAccessor在创建用作服务的dbcontext之前进行初始化

时间:2018-03-15 13:45:43

标签: asp.net-core dependency-injection .net-core entity-framework-core

我们正在为我们的应用程序使用每个租户逻辑数据库。 我们目前需要根据当前登录的用户动态构建连接字符串。

我们真的想将租户数据库上下文用作服务(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")));

2 个答案:

答案 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,这应仅用于创建迁移。