如何在asp.net核心中间件中做DI? [英] How to do DI in asp.net core middleware?
问题描述
我试图按如下方式将依赖项注入我的中间件构造函数中
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);
}
因为中间件是在应用启动时构建的,而不是按请求构建的,所以中间件构造函数使用的作用域生存期服务不会在每次请求期间与其他依赖项注入类型共享.如果必须在中间件和其他类型之间共享作用域服务,请将这些服务添加到
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. TheInvoke
method can accept additional parameters that are populated by DI:
这篇关于如何在asp.net核心中间件中做DI?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!