解析DBContext实现了Asp中的另一个接口.净的核心
本文关键字:另一个 接口 核心 DBContext 实现 Asp 解析 | 更新日期: 2023-09-27 18:14:37
我有一个EF Context,它有它的签名
public class MyContext : DbContext, IDbContext
{
}
当我将它添加到服务中时,我使用它
services.AddDbContext<MyContext>(op =>
{
op.UseSqlServer(configuration.GetConnectionString("DefaultConnection"));
});
但是当我注入IDbContext时就会产生问题,像这样
services.AddScoped(typeof(IDbContext), typeof(MyContext));
因为它复制了我的DbContext,每个请求应该只有一个。
如何解决?
在您的情况下,使用工厂方法应该可以正常工作。
services.AddScoped<IDbContext>(provider => provider.GetService(typeof(MyContext)));
这样,您将解析MyDbContext
的新实例(在第一次调用时)或在结论性调用的请求期间返回它的已经实例化的实例。
请注意,如果您正在注册多个不同的DbContexts,则必须使用正确的特定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 Quick Action模板创建的:(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) { ... }
现在可以正常工作了