我很困惑,是一个类型的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();
字符串
2条答案
按热度按时间bnlyeluc1#
好吧,就我个人而言,我不具备理解其抽象、间接和一般黑魔法的某些微软口径,但 * 理论上 * 你可以为自己check out the source code。这真的很酷。
注册中间件
最后,您放入
Program.cs
中的所有app.UseMyCoolMiddleware()
调用都以ApplicationBuilder.Use(Func<RequestDelegate, RequestDelegate> middleware)
结束:字符串
您会注意到,此时的中间件只是一个
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。
pxyaymoc2#
为了理解下一个.Invoke(上下文),最好多了解ASP.NET核心中间件。
基于ASP.Net Core Documentation():
中间件是组装到应用程序管道中以处理请求和响应的软件。每个组件:
选择是否将请求传递到管道中的下一个组件。可以在管道中的下一个组件之前和之后执行工作。请求委托用于构建请求管道。请求委托处理每个HTTP请求。换句话说,您将一个请求委托注入到中间件中,您可以选择在路径中继续调用Next方法。
的数据
下图描述了请求处理管道和自定义委托的顺序。
的