如何在asp.net核心中间件中做DI? [英] How to do DI in asp.net core middleware?

查看:110
本文介绍了如何在asp.net核心中间件中做DI?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图按如下方式将依赖项注入我的中间件构造函数中

I am trying to inject dependency into my middleware constructor as follows

public class CreateCompanyMiddleware
{
    private readonly RequestDelegate _next;
    private readonly UserManager<ApplicationUser> _userManager;

    public CreateCompanyMiddleware(RequestDelegate next
        , UserManager<ApplicationUser> userManager
        )
    {
        _next = next;
    }

    public async Task Invoke(HttpContext context)
    {
        await _next.Invoke(context);
    }
}

我的Startup.cs文件看起来像

My Startup.cs file looks like

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<ApplicationDbContext>(options =>
        options.UseMySql(Configuration.GetConnectionString("IdentityConnection")));

    services.AddIdentity<ApplicationUser, IdentityRole>()
        .AddEntityFrameworkStores<ApplicationDbContext>()
        .AddDefaultTokenProviders();
    ...

    app.UseMiddleware<CreateCompanyMiddleware>();

    ...

但是我收到此错误

启动应用程序时发生错误. InvalidOperationException:无法从根提供者解析作用域服务'Microsoft.AspNetCore.Identity.UserManager`1 [Common.Models.ApplicationUser]'. Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteValidator.ValidateResolution(类型serviceType,IServiceScope范围,IServiceScope rootScope)

An error occurred while starting the application. InvalidOperationException: Cannot resolve scoped service 'Microsoft.AspNetCore.Identity.UserManager`1[Common.Models.ApplicationUser]' from root provider. Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteValidator.ValidateResolution(Type serviceType, IServiceScope scope, IServiceScope rootScope)

推荐答案

UserManager<ApplicationUser>(默认情况下)已注册为作用域依赖项,而您的CreateCompanyMiddleware中间件是在应用启动时构建的(有效地使其成为 singleton ).这是一个相当标准的错误,它表明您不能将 scoped 依赖项放入 singleton 类中.

UserManager<ApplicationUser> is (by default) registered as a scoped dependency, whereas your CreateCompanyMiddleware middleware is constructed at app startup (effectively making it a singleton). This is a fairly standard error saying that you can't take a scoped dependency into a singleton class.

在这种情况下,修复很简单-您可以将UserManager<ApplicationUser>注入到Invoke方法中:

The fix is simple in this case - you can inject the UserManager<ApplicationUser> into your Invoke method:

public async Task Invoke(HttpContext context, UserManager<ApplicationUser> userManager)
{
    await _next.Invoke(context);
}

ASP.NET核心中间件:按请求的中间件依赖性:

因为中间件是在应用启动时构建的,而不是按请求构建的,所以中间件构造函数使用的作用域生存期服务不会在每次请求期间与其他依赖项注入类型共享.如果必须在中间件和其他类型之间共享作用域服务,请将这些服务添加到Invoke方法的签名中. Invoke方法可以接受由DI填充的其他参数:

Because middleware is constructed at app startup, not per-request, scoped lifetime services used by middleware constructors aren't shared with other dependency-injected types during each request. If you must share a scoped service between your middleware and other types, add these services to the Invoke method's signature. The Invoke method can accept additional parameters that are populated by DI:

这篇关于如何在asp.net核心中间件中做DI?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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