使用在Asp.Net Core中实现另一个接口来解析DBContext

时间:2016-10-24 21:14:45

标签: c# asp.net-core entity-framework-core

我有一个具有签名的EF上下文

public class MyContext : DbContext, IDbContext
{

}

当我将它添加到服务时,我使用它

services.AddDbContext<MyContext>(op =>
{
    op.UseSqlServer(configuration.GetConnectionString("DefaultConnection"));
});

但是当我注入IDbContext时会导致问题,比如

services.AddScoped(typeof(IDbContext), typeof(MyContext));

因为它复制了我的DbContext,而且每个请求应该只有一个。

我该如何解决?

2 个答案:

答案 0 :(得分:5)

在您的情况下使用工厂方法应该可以正常工作。

services.AddScoped<IDbContext>(provider => provider.GetService(typeof(MyContext)));

通过这种方式,您将解析MyDbContext的新实例(在第一次调用时)或在最终调用请求期间返回已实例化的实例。

答案 1 :(得分:0)

请注意,如果要注册多个不同的DbContext,则必须使用正确的特定DbContextOptions正确定义构造函数。如果您不这样做,则冒着被DI解决不正确类型的风险。

例如,我使用的是MyContext : DbContext, IDbContext,类似于OP,但是我也使用的是通用的DbContext用于OpenIddict的临时存储:

services.AddDbContext<DbContext>(o =>
            {
                o.UseInMemoryDatabase(nameof(DbContext)); //tokens and stuff is stored in memory, not the actual users or passwords. 
                o.UseOpenIddict();
            });

至关重要的是,我的MyContext构造函数太通用了-使用Visual Studio快速操作模板创建的:( ugh

错误:

public MyContext (DbContextOptions options) : base(options) { ... } 

这将导致DI在运行时解析错误的DbContext:

Microsoft.EntityFrameworkCore.Infrastructure:Information: Entity Framework Core 2.1.4-rtm-31024 initialized 'MyContext' using provider 'Microsoft.EntityFrameworkCore.InMemory' with options: StoreName=DbContext

有时候,我遇到一个错误,抱怨我的上下文没有正确的构造函数类型,因此我将构造函数更改为:

正确:

public MyContext (DbContextOptions<MyContext> options) : base(options) { ... } 

,现在可以正常使用了。