gpt4 book ai didi

c# - 依赖注入(inject)如何与中间件一起工作?

转载 作者:行者123 更新时间:2023-12-05 02:46:08 24 4
gpt4 key购买 nike

我看到了一些类似这样的代码:

public class CustomMiddleware {
private RequestDelegate next;

public CustomMiddleware (RequestDelegate nextDelegate) {
next = nextDelegate;
}

public async Task Invoke(HttpContext context, IResponseFormatter formatter) {
...
await next(context);
}
}

并且 IResponseFormatter 服务注册为:

public void ConfigureServices(IServiceCollection services) {
services.AddTransient<IResponseFormatter, GuidService>();
}

我知道DI是怎么工作的,但是我对中间件工作原理的理解是,next(RequestDelegate)代表下一个中间件的Invoke方法,所以在 CustomMiddleware 中,即使是第二个参数也是由 DI 解析的,但是 RequestDelegate 的定义是

public delegate Task RequestDelegate(HttpContext context);

CustomMiddleware 之前的中间件是如何知道 CustomMiddlewareInvoke 方法因为有一个额外的参数而改变的?它无法预先知道,因此前一个中间件的 next RequestDelegateCustomMiddlewareInvoke 的签名不匹配> 方法?

最佳答案

How does the previous middleware before CustomMiddleware know that CustomMiddleware's Invoke method has changed by having an extra argument?

因为惯例(和反射(reflection))。

自定义中间件不继承任何接口(interface)或基类,因此运行时知道如何使用中间件的唯一方法是 convention :

The middleware class must include:

  • A public constructor with a parameter of type RequestDelegate.
  • A method named Invoke or InvokeAsync. This method must:
    • Return a Task.
    • Accept a first parameter of type HttpContext.

有了这些知识,就可以安全地运行中间件:您可以使用反射来获取 Invoke 的依赖项并在知道返回类型为 Task 的情况下执行它。例如:

MethodInfo method = middleware.GetType().GetMethod("Invoke");
ParameterInfo[] parameters = method.GetParameters();
// ... instatiate the dependencies using something like ServiceProvider
// and bundle them up into an object[].
method.Invoke(middleware/**, injected dependencies go here as an object[] **/);

It cannot know in advance, therefore the previous middleware's next RequestDelegate does't match the signature of CustomMiddleware's Invoke method?

RequestDelegateCustomMiddleware.Invoke 的签名不匹配。
RequestDelegate不需要匹配CustomMiddleware.Invoke的签名。

所有 RequestDelegate (next) 关心的是将相同的 HttpContext 实例传递到中间件链中,它总是有那个,因为的(前面提到的)约定(强调):

  • A method named Invoke or InvokeAsync. This method must:
    • Return a Task.
    • Accept a first parameter of type HttpContext.

最后,next 并不是直接调用CustomMiddleware.Invoke。在中间件之间,DI 有机会注入(inject)下一个中间件所需的服务。

关于c# - 依赖注入(inject)如何与中间件一起工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65631232/

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