Use Method如何在.net核心中间件中找到下一个委托?

im9ewurl  于 2023-08-08  发布在  .NET
关注(0)|答案(2)|浏览(114)

我很困惑,是一个类型的RequestDelegate如何在这里找到下一个委托?比如await next.Invoke(context)如何调用下面的方法?我知道同样的上下文正在作为下一个参数传递。但是如何调用下一个有序的方法呢?

var builder=WebApplication.CreateBuilder(args);
var app=builder.Build();    

app.Use(async (HttpContext context,RequestDelegate next) =>
{
    await context.Response.WriteAsync("HelloOne ");
    await next.Invoke(context);
});
app.Use(async (HttpContext context, RequestDelegate next) => {
    await context.Response.WriteAsync("HelloTwo");
    await next.Invoke(context);

});
app.Run();

字符串

bnlyeluc

bnlyeluc1#

好吧,就我个人而言,我不具备理解其抽象、间接和一般黑魔法的某些微软口径,但 * 理论上 * 你可以为自己check out the source code。这真的很酷。

注册中间件

最后,您放入Program.cs中的所有app.UseMyCoolMiddleware()调用都以ApplicationBuilder.Use(Func<RequestDelegate, RequestDelegate> middleware)结束:

//Adds the middleware to the application request pipeline.
public IApplicationBuilder Use(Func<RequestDelegate, RequestDelegate> middleware)
{
    _components.Add(middleware);
    _descriptions?.Add(CreateMiddlewareDescription(middleware));

    return this;
}

字符串
您会注意到,此时的中间件只是一个Func。这是在UseMiddlewareExtensions.cs中生成的,即UseMiddleware()的重载之一(然后调用上面的Use()方法)。其中有一种巫术,它通过尝试找到一个名为“Invoke”的方法并找出要注入的依赖关系等,将中间件类/类型转换为Func<RequestDelegate, RequestDelegate>
如果向上滚动ApplicationBuilder.cs,您将看到“请求管道”只是一个普通的旧List,类似于Func<RequestDelegate, RequestDelegate>RequestDelegate是一个异步函数,它接受HttpContext,但不返回任何内容:就像中间件的Invoke方法一样。这些Func(基本上)是中间件的构造器。它们接收以下中间件的Invoke方法并返回自己的方法。

构建管道

现在,这只是Program.cs中的配置内容,仅在服务器启动时运行一次。调用app.Run()将管道设置标记为完成,并准备所有中间件。如果您有自定义的中间件,您可以逐步查看,并看到这是以相反的顺序调用它们的构造函数的时候。最后一个RequestDelegate,你会注意到它被称为“app”。它是初始中间件的Invoke方法,即管道的入口点。

运行

显然这就是它变得有趣的地方。管道实际上是如何在每个请求中调用的?我不知道,但不知何故,当Kestrel(?)接收到一个请求,它创建一个HttpContext,用所有相关的东西填充它,并将它交给前面提到的初始中间件。然后它要么完成它的任务并将HttpContext传递给下一个中间件,要么调用下一个中间件然后执行它的任务,要么执行它的任务并返回(一个“短路”中间件,例如用于提供静态文件的中间件)。如果它找到请求的文件,它不需要运行路由等)。
祝你好运,lol。

pxyaymoc

pxyaymoc2#

为了理解下一个.Invoke(上下文),最好多了解ASP.NET核心中间件。
基于ASP.Net Core Documentation():
中间件是组装到应用程序管道中以处理请求和响应的软件。每个组件:
选择是否将请求传递到管道中的下一个组件。可以在管道中的下一个组件之前和之后执行工作。请求委托用于构建请求管道。请求委托处理每个HTTP请求。换句话说,您将一个请求委托注入到中间件中,您可以选择在路径中继续调用Next方法。


的数据
下图描述了请求处理管道和自定义委托的顺序。

相关问题