我正在阅读有关.Net Core中DI的MS文档。
https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-2.2
我碰到了线
“警告
在中间件中使用范围服务时,将服务注入 Invoke或InvokeAsync方法。不要通过构造函数注入 注入,因为它迫使服务的行为像单例一样。”
任何人,请解释一下这是什么意思?
然后,这里投票最多的答案之一是将构造函数DI注入用于范围服务。 AddTransient, AddScoped and AddSingleton Services Differences?
答案 0 :(得分:1)
这是很重要的事情。 您的中间件类仅实例化一次,即其构造函数仅运行一次。 如果您的依赖项的生存期为作用域或瞬态,则意味着生存期较短。 如果您通过构造函数要求这种依赖关系,则中间件将依赖寿命较短的服务。 在请求完成后,DI容器可以处理该服务,从而使中间件具有不再可用的服务。
通过在运行时在Invoke / InvokeAsync函数中进行请求, 您可以使用瞬态和范围依赖性。 构造函数中可能需要单例,因为单例具有与中间件相同的生存期。
答案 1 :(得分:0)
这记录在ASP.NET Core中间件Per-request dependencies中。
因为中间件是在应用启动时构建的,而不是按请求构建的,所以中间件构造函数使用的范围内的生存期服务不会在每次请求期间与其他依赖项注入类型共享。如果必须在中间件和其他类型之间共享作用域服务,请将这些服务添加到Invoke方法的签名中。 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);
}
}