gpt4 book ai didi

c# - 在 ASP.NET Core 中间件构造函数中混合依赖注入(inject)和手动传递参数

转载 作者:行者123 更新时间:2023-12-02 11:13:04 32 4
gpt4 key购买 nike

我正在为 ASP.NET Core 2.2 编写一个自定义中间件。根据Microsoft Docs关于编写自定义中间件:

Middleware components can resolve their dependencies from dependency injection (DI) through constructor parameters. UseMiddleware<T> can also accept additional parameters directly.

这看起来一切都很好,但它没有说明当我混合两种方式时会发生什么,例如使用DI并在UseMiddleware<T>中传递参数。例如,我有以下中间件:

public class CustomMiddleware
{
public CustomMiddleware(RequestDelegate next, ILogger<CustomMiddleware> logger, CustomMiddlewareOptions options)
{
...
}

public async Task InvokeAsync(HttpContext context)
{
...
}

哪里logger由 DI 和 options 提供提供如下:

app.UseMiddleware<CustomMiddleware>(new CustomMiddlewareOptions());

我自己对 2.2 的测试似乎表明这工作正常,并且构造函数中参数的顺序并不重要(我可以将 DI 参数放在手动传递的参数之前或之后,甚至放在两个手动传递的参数之间 -传递参数)。但我正在寻找一些保证,证明我所做的事情是正确的。如果有人能指出一些支持这种用法的文档或源代码,那就太好了。谢谢!

最佳答案

My own testing with 2.2 seems to show that this works fine, and the order of the parameters in the constructor doesn't matter (I can place DI parameter before or after manually-passed parameter, or even in between two manually-passed parameters). But I'm looking for some assurances

是的。看完源码,我觉得没问题。

它是如何工作的

您的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);

这里是args (Given Arguments) 是您传递到 UseMiddleware<CustomMiddleware>(args) 的参数数组。 (没有 next )。

准备构造函数参数有两个阶段:

  1. 匹配给定的 args针对构造参数类型。并在类型匹配时设置值。请参阅source code Here
  2. 填写null元素使用 ServiceProvider.GetRequiredService<SomeService>() .参见source code here 。如果服务实例仍然是null ,然后使用default值。

例如,假设:

  1. 您有一个符合约定的中间件,其构造函数具有以下签名:
    public CustomMiddleware(RequestDelegate next, A a, B b, C c, D d, E e){ ... }
  2. 然后我们在注册中间件时传入两个参数:

    app.UseMiddleware(c, a) 

    哪里cC 的一个实例类型,和aA 的一个实例类型。所以givenParameters数组是[next,c, a]

创建 CustomMiddleware 的实例,编译器需要知道完整的构造函数参数值。 DI 扩展在两个阶段内获取此构造函数参数值数组 ( _parameterValues )。参见:

enter image description here

stage2 的工作方式如下:

b'= sp.GetService(B); 
if b' == null :
b' = default value of B

正如您在上面看到的,ActivatorUtilities.CreateInstance(sp,mw,args) API 自动处理顺序和缺失参数。

<小时/>

顺便说一句,按照惯例,中间件在启动时激活,并且始终是单例。如果您想使用范围服务,请参阅this thread

关于c# - 在 ASP.NET Core 中间件构造函数中混合依赖注入(inject)和手动传递参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59389039/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com