我正在阅读有关.Net Core中DI的MS文档。
https://learn.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-2.2
我遇到了这条线
"警告
在中间件中使用作用域服务时,将服务注入到 调用或调用异步方法。不要通过构造函数注入 注入,因为它迫使服务表现得像单例。
任何人,请解释一下这是什么意思?
然后,这里投票最多的答案之一使用构造函数 DI 注入进行作用域服务。AddTransient、AddScoped 和 AddSingleton Services 的区别?
记录在 ASP.NET 核心中间件:每个请求依赖项中。
由于中间件是在应用启动时构造的,而不是按请求构造的,因此中间件构造函数使用的范围生存期服务在每个请求期间不会与其他依赖项注入类型共享。如果必须在中间件和其他类型的类型之间共享作用域服务,请将这些服务添加到 Invoke 方法的签名中。调用方法可以接受由 DI 填充的其他参数:
public class CustomMiddleware
{
private readonly RequestDelegate _next;
public CustomMiddleware(RequestDelegate next)
{
_next = next;
}
// IMyScopedService is injected into Invoke
public async Task Invoke(HttpContext httpContext, IMyScopedService svc)
{
svc.MyProperty = 1000;
await _next(httpContext);
}
}
这是一件非常重要的事情。中间件类只实例化一次,即它的构造函数只运行一次。如果依赖项的生存期为范围或暂时性,则其生存期较短。如果通过构造函数需要此类依赖项,则中间件依赖于生存期较短的服务。DI 容器可以在请求完成后释放服务,使中间件不再工作。
通过在运行时在 Invoke/InvokeAsync 函数中请求它,可以使用暂时性和作用域内的依赖项。构造函数中可能需要单例,因为它们与中间件具有相同的生存期。