sch*_*nyw 5 c# dependency-injection asp.net-core asp.net-core-middleware asp.net-core-2.2
我正在为 ASP.NET Core 2.2 编写自定义中间件。根据编写自定义中间件的Microsoft Docs:
中间件组件可以通过构造函数参数从依赖注入(DI)中解析它们的依赖关系。
UseMiddleware<T>也可以直接接受附加参数。
这看起来都不错,但它并没有说明当我混合这两种方式时会发生什么,例如使用 DI 并在UseMiddleware<T>. 例如,我有以下中间件:
public class CustomMiddleware
{
public CustomMiddleware(RequestDelegate next, ILogger<CustomMiddleware> logger, CustomMiddlewareOptions options)
{
...
}
public async Task InvokeAsync(HttpContext context)
{
...
}
Run Code Online (Sandbox Code Playgroud)
wherelogger由 DI 提供,options其提供方式如下:
app.UseMiddleware<CustomMiddleware>(new CustomMiddlewareOptions());
Run Code Online (Sandbox Code Playgroud)
我自己对 2.2 的测试似乎表明这可以正常工作,并且构造函数中参数的顺序无关紧要(我可以将 DI 参数放在手动传递的参数之前或之后,甚至在两个手动传递的参数之间) . 但我正在寻找一些保证,即我所做的一切都没有问题。如果有人能指出一些支持这种用法的文档或源代码,那就太好了。谢谢!
我自己对 2.2 的测试似乎表明这工作正常,并且构造函数中参数的顺序并不重要(我可以将 DI 参数放在手动传递的参数之前或之后,甚至放在两个手动传递的参数之间) 。但我正在寻找一些保证
是的。看完源码,我觉得还可以。
您CustomMiddleware是一个常规中间件(与基于工厂的中间件不同),由ActivatorUtilities.CreateInstance(app.ApplicationServices, middleware, ctorArgs)激活:
var ctorArgs = new object[args.Length + 1];
ctorArgs[0] = next;
Array.Copy(args, 0, ctorArgs, 1, args.Length); //
var instance = ActivatorUtilities.CreateInstance(app.ApplicationServices, middleware, ctorArgs);
Run Code Online (Sandbox Code Playgroud)
这里的(Given Arguments) 是您传递到(不带)args的参数数组。UseMiddleware<CustomMiddleware>(args)next
准备构造函数参数有两个阶段:
args与构造参数类型进行匹配。并在类型匹配时设置值。请参阅此处的源代码null使用填充元素。ServiceProvider.GetRequiredService<SomeService>()请参阅此处的源代码。如果服务实例仍然是null,则使用该default值。例如,假设:
public CustomMiddleware(RequestDelegate next, A a, B b, C c, D d, E e){ ... }
Run Code Online (Sandbox Code Playgroud)然后我们在注册中间件时传入两个参数:
app.UseMiddleware(c, a)
Run Code Online (Sandbox Code Playgroud)
其中c是 Type 的实例C,a是 Type 的实例A。所以givenParameters数组是[next,c, a]
要创建 的实例CustomMiddleware,编译器需要知道完整的构造函数参数值。_parameterValuesDI 扩展在两个阶段内获取此构造函数参数值数组 ( )。参见:
stage2 的工作方式如下:
b'= sp.GetService(B);
if b' == null :
b' = default value of B
Run Code Online (Sandbox Code Playgroud)
正如您在上面看到的,ActivatorUtilities.CreateInstance(sp,mw,args)API 自动处理顺序和缺失的参数。
附带说明一下,按照惯例,中间件在启动时被激活,并且始终是单例的。如果您想使用范围服务,请参阅此线程
| 归档时间: |
|
| 查看次数: |
1718 次 |
| 最近记录: |