【发布时间】:2019-11-21 04:16:12
【问题描述】:
我在使用 EF Core 时遇到了一个奇怪的问题,我不明白为什么......
public class Startup
{
static Config Config;
public Startup(IConfiguration configuration)
{
Config = new Config();
configuration.Bind(Config);
}
public void ConfigureServices(IServiceCollection services)
{
services.AddHttpContextAccessor();
services.AddScoped(ctx => ctx.GetService<IHttpContextAccessor>()?.HttpContext);
services.AddScoped(ctx => ctx.GetService<HttpContext>()?.Request);
services.AddAuthInfo();
services.AddSingleton(Config);
services.AddDbContext<MembershipDataContext>(options => options.UseSqlServer(Config.Connections["Membership"]));
services.AddDbContext<CoreDataContext>(options => options.UseSqlServer(Config.Connections["Core"]));
services.AddDbContext<B2BDataContext>(options => options.UseSqlServer(Config.Connections["B2B"]));
services.AddScoped<IMembershipDataContext, MembershipDataContext>();
services.AddScoped<ICoreDataContext, CoreDataContext>();
services.AddScoped<IB2BDataContext, B2BDataContext>();
...
...我从每个请求中提取自定义身份验证信息并将其注入到我的 DbContexts 中。
由于初始化过程,我必须有一个接受 DbContextOptions 的 CTOR,所以我简单地添加了第二个,希望它会调用正确的...
public EFDataContext(DbContextOptions options, IAuthInfo auth) : base(options) { AuthInfo = auth; }
public EFDataContext(DbContextOptions options) : base(options) { }
...在运行时,我看到两个 CTOR 在一个请求中多次被命中(不是我所期望的)。
从其他帖子中,我注意到很多人说我不需要最后三行,但删除它们会给我带来异常,告诉我其他对象不能再由 DI 构造。
所以我很困惑......
我如何让这个工作,以便我只能为每个请求构建 1 个实例,并且只在我这样做时使用最多的参数命中 CTOR?
【问题讨论】:
-
您为什么要为您的上下文使用
AddScoped?AddDbContext会将它们添加为范围服务。 -
问题中已经解释过了
-
嗯,我不确定你是否可以扩展 DbContext 构造函数,我没有尝试过,但我没有尝试过的原因是因为我认为你不应该将身份验证信息注入其中首先。
-
这是一个自定义对象,用于帮助我确定数据库中包含事务信息的多租户上下文,基于过滤器被修改的上下文......这在 EF6 中完美运行......没有不过没关系,关键是 EF Contexts 首先应该能够接受其他参数作为 DI 标准前提的一部分。
-
@DavidG 我发现了... :)
标签: c# asp.net-core dependency-injection entity-framework-core