使用 DbContext 接口注册 AspNetCore 2.1 身份系统 [英] Register AspNetCore 2.1 Identity system with DbContext interface

查看:17
本文介绍了使用 DbContext 接口注册 AspNetCore 2.1 身份系统的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个 AspNetCore 2.1 WebApi.我正在使用 Microsoft.Extensions.DependencyInjectionAspNetCore.IdentityEntityFrameworkCore.

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 类(UserManagerRoleManager 等)无法在依赖注入容器中重新解析,因为它们使用的身份存储(UserStoreRoleStore 等)无法解析它们的 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 中注册.该扩展需要一个 class,它可以解析为 DbContext - 我不能向接口 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 时,你注册了一个 scoped 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆