使用DbContext接口注册AspNetCore 2.1身份系统 [英] Register AspNetCore 2.1 Identity system with DbContext interface
问题描述
我正在研究AspNetCore 2.1 WebApi.我正在使用Microsoft.Extensions.DependencyInjection
,AspNetCore.Identity
和EntityFrameworkCore
.
I am working on an AspNetCore 2.1 WebApi. I am using Microsoft.Extensions.DependencyInjection
, AspNetCore.Identity
, and EntityFrameworkCore
.
在我的DI注册中,我打电话:
In my DI registrations, I am calling:
services.AddDbContext<IMyDbContext, MyDbContext>();
好吧?传递合同.但是然后我遇到一个例外,即Identity Manager类(UserManager
,RoleManager
等)无法在依赖注入容器中重新分配,因为它们使用的身份存储(UserStore
,RoleStore
等)不能解析其DI参数(MyDbContext
).
Good, right? Pass around the contract. But then I hit an exception that the Identity Manager classes (UserManager
, RoleManager
, etc.) cannot be respolved in the Dependency Injection container because the Identity Stores they use (UserStore
, RoleStore
, etc.) cannot resolve their DI parameter (MyDbContext
).
设置身份时,所有内容都指向此行:
It all points to this line when setting up Identity:
builder.AddEntityFrameworkStores<MyDbContext>();
...这很奇怪,因为身份存储正在寻找具体的上下文,并且未在DI中注册.该扩展期望它可以解析为DbContext
的class
,并且我不能在接口IMyDbContext
上添加隐式运算符以为其提供DI扩展方法可以使用的隐式强制转换.
... which is puking since the Identity Stores are looking for the concrete context and it is not registered with DI. The extension is expecting a class
that it can resolve down to DbContext
- and I cannot add an implicit operator to the interface IMyDbContext
to give it an implicit cast the DI extension method could use.
所有这些使我执行了相当难看的DI注册:
All this has me performing a rather ugly DI registration:
services
.AddDbContext<IMyDbContext, MyDbContext>()
.AddDbContext<MyDbContext>();
- DI注册可能会导致我尚未遇到的其他下游问题(线程安全,事务性).
我的猜测是,我可以滚动自己的IServiceCollection
扩展名和/或自定义身份存储来清理DI注册-这在这里似乎实在是太过分了,因为否则我无需超出默认的内置身份商店.
My guess is that I could clean up the DI registration by rolling my own IServiceCollection
extension and/or custom Identity Stores - which really seems like overkill here as I otherwise have no need to go beyond the default built-in Identity Stores.
我也不是很想删除<interface, concrete>
上下文注册,因为这会滴加到我所有的构造函数注入中,而且看起来错误.
I also don't really want to remove the <interface, concrete>
context registration as that will trickle down to all my constructor injections, and just seems wrong.
有人解决了这个问题并找到了解决方法吗? 还是至少有人可以确认/否认DI中的双重(接口和具体)上下文注册不会引起其他问题?
Has anybody tackled this already and found a work-around? Or can anybody at least confirm/deny that the double (interface && concrete) context registration in the DI will not cause other issues?
提前谢谢!
推荐答案
默认情况下,调用AddDbContext
时,您注册了作用域 DbContext
实例.这意味着在处理单个请求的任何地方,通过DI请求所述DbContext
都会给您相同实例.进行双重注册后,DI系统会根据您要求的是IMyDbContext
还是MyDbContext
,为您提供不同的实例.
By default, when you call AddDbContext
, you register a scoped DbContext
instance. This means that anywhere within the handling of a single request, requesting said DbContext
via DI will give you the same instance. With the double registration you have, the DI system will give you a different instance depending upon whether you ask for an IMyDbContext
or a MyDbContext
.
要指示DI系统为您提供两种类型的相同实例,请使用以下方法:
To instruct the DI system to give you the same instance for both types, use the following approach:
services.AddDbContext<MyDbContext>();
services.AddScoped<IMyDbContext>(sp => sp.GetRequiredService<MyDbContext>());
第一个调用注册MyDbContext
,第二个简单地将对IMyDbContext
的请求转发到同一作用域MyDbContext
实例.
The first call registers MyDbContext
and the second simply forwards requests for IMyDbContext
to that same scoped MyDbContext
instance.
这篇关于使用DbContext接口注册AspNetCore 2.1身份系统的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!