使用DbContext接口注册AspNetCore 2.1身份系统

cha*_*oup 4 c# entity-framework dependency-injection asp.net-identity asp.net-core

我正在研究AspNetCore 2.1 WebApi。我使用Microsoft.Extensions.DependencyInjectionAspNetCore.IdentityEntityFrameworkCore

在我的DI注册中,我打电话给:

services.AddDbContext<IMyDbContext, MyDbContext>();
Run Code Online (Sandbox Code Playgroud)

好吧 通过合同。但后来我打了一个异常的Identity Manager类(UserManagerRoleManager,等)不能在依赖注入容器respolved,因为他们使用的标识存储(UserStoreRoleStore,等)无法解析其DI参数(MyDbContext)。

设置身份时,所有这些都指向此行:

builder.AddEntityFrameworkStores<MyDbContext>();
Run Code Online (Sandbox Code Playgroud)

...之所以如此,是因为身份存储正在寻找具体的上下文,并且未在DI中注册。扩展期望class它可以解析为DbContext-并且我不能在接口中添加隐式运算符IMyDbContext以为其提供DI扩展方法可以使用的隐式转换。

所有这些使我执行了相当难看的DI注册:

services
        .AddDbContext<IMyDbContext, MyDbContext>()
        .AddDbContext<MyDbContext>();
Run Code Online (Sandbox Code Playgroud)
  • DI注册可能会导致我尚未遇到的其他下游问题(线程安全,事务性)。

我的猜测是,我可以通过滚动自己的IServiceCollection扩展名和/或自定义身份存储来清理DI注册-这在这里似乎实在是太过分了,因为否则我无需超出默认的内置身份存储。

我也不是很想删除<interface, concrete>上下文注册,因为这会滴加到我所有的构造函数注入中,这似乎是错误的

是否有人已经解决了这个问题并找到了解决方法?还是至少有人可以确认/否认DI中的双重(界面&&具体)上下文注册不会引起其他问题?

提前致谢!

Kir*_*kin 10

默认情况下,当您调用时AddDbContext,您将注册一个作用域 DbContext实例。这意味着在处理单个请求的任何地方,DbContext通过DI进行请求都会给您相同的实例。使用双重注册后,DI系统将根据您要输入还是给出不同的实例IMyDbContextMyDbContext

要指示DI系统为您提供两种类型的相同实例,请使用以下方法:

services.AddDbContext<MyDbContext>();
services.AddScoped<IMyDbContext>(sp => sp.GetRequiredService<MyDbContext>());
Run Code Online (Sandbox Code Playgroud)

第一个调用注册MyDbContext,第二个简单地转发对IMyDbContext相同作用域MyDbContext实例的请求。