从来好事天生俭,自古瓜儿苦后甜。这篇文章主要讲述ASP.NET Core 3.1--中间件源码解读--RequestDelegate--ApplicationBuilder.Use相关的知识,希望能为你提供帮助。
一、RequestDelegate的定义
从RequestDelegate定义可以看出,RequestDelegate是接收请求上下文HttpContext的一个委托,RequestDelegate既然是一个委托,委托就是一个方法,所以RequestDelegate就是个方法,是个接受请求上下文的方法。
public delegate Task RequestDelegate(HttpContext context);
二、 IApplicationBuilder.Use的定义
我们对比来看,下面这个func是接收1个int 类型的参数,返回1个string类型的委托
Func< int, string> func = new Func< int, string> (i => { return "abc"; }); string result = func(123);
在看ApplicationBuilder.Use()的定义
ApplicationBuilder.Use方法接收1个Func委托,这个Func接收1个RequestDelegate类型的参数,返回1个RequestDelegate类型,上面说了RequestDelegate是个方法,那么也就是说ApplicationBuilder.Use方法接收1个方法,返回1个方法。
IApplicationBuilder Use(Func< RequestDelegate, RequestDelegate> middleware);
三、ApplicationBuilder.Use需要的参数的简写
这时候requestdelegate是个方法,但是是什么方法,我们还不知道,我们往下看
//1、Func委托,这个Func接收1个RequestDelegate类型的参数,返回1个RequestDelegate类型 Func< RequestDelegate, RequestDelegate> func = new Func< RequestDelegate, RequestDelegate> ((RequestDelegate requestdelegate) => { return new RequestDelegate(async (context) => { await context.Response.WriteAsync("接收1个带RequestDelegate类型的参数,返回RequestDelegate类型的委托"); }); }); //2、简写这个委托 Func< RequestDelegate, RequestDelegate> func = (requestdelegate => { return new RequestDelegate(async (context) => { await context.Response.WriteAsync("简写func委托!"); }); }); //3、Use中间件,最终简写 app.Use(requestdelegate => { return new RequestDelegate(async (context) => { await context.Response.WriteAsync("Use中间件!"); }); });
四、看源码解读中间件注册和执行流程
1、为什么输出顺序是This is Middleware 3=> This is Middleware 2=> This is Middleware 1? 2、为什么输出顺序是This is Hello World 1 Start=> This is Hello World 2 Start=> This is Hello World 3 Start=> This is Hello World 3 End=> This is Hello World 2 End=> This is Hello World 1 End?
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory) { app.Use(next => { Console.WriteLine("This is Middleware 1"); return new RequestDelegate( async context => { await context.Response.WriteAsync("This is Hello World 1 Start"); await next.Invoke(context); await context.Response.WriteAsync("This is Hello World 1 End"); }); }); app.Use(next => { Console.WriteLine("This is Middleware 2"); return new RequestDelegate( async context => { await context.Response.WriteAsync("This is Hello World 2 Start"); await next.Invoke(context); await context.Response.WriteAsync("This is Hello World 2 End"); }); }); app.Use(next => { Console.WriteLine("This is Middleware 3"); return new RequestDelegate( async context => { await context.Response.WriteAsync("This is Hello World 3 Start"); await context.Response.WriteAsync("This is Hello World 3 End"); }); }); }
文章图片
1、ApplicationBuilder.Use方法源码解读
从源码看出ApplicationBuilder.Use方法就是把Func< RequestDelegate, RequestDelegate> middleware添加到_components这个集合里,而从_components的定义看出_components是个委托集合。
文章图片
文章图片
2、中间件执行源码解读
Build()的时候执行注册的中间件 从源码看出有个默认的RequestDelegate app,把委托集合反转,遍历执行。 第3个中间件的next是默认的RequestDelegate app=> 第2个中间件的next是第3个中间件的返回值=> 第1个中间件的next是第2个中间件的返回值 所以先输出This is Middleware 3,后输出This is Middleware 2,最后输出This is Middleware 1,最终返回的是第1个中间件,最终Application就是Middleware 1。 所以最后的输出顺序是This is Hello World 1 Start---> This is Hello World 2 Start---> This is Hello World 3 Start---> This is Hello World 3 End---> This is Hello World 2 End---> This is Hello World 1 End
文章图片
总结中间件:
1、中间件就像俄罗斯套娃一样,一环套一环 2、最后返回的是第1个中间件
【ASP.NET Core 3.1--中间件源码解读--RequestDelegate--ApplicationBuilder.Use】
文章图片
推荐阅读
- wxappUnpkg
- Android | 瓒呯畝鍗曢泦鎴怘MS ML Kit瀹炵幇鏈€澶ц劯寰瑧鎶撴媿
- appium +夜神模拟器 操作元素
- 手机上写歌词的软件,原创歌词创作软件app下载,有吗()
- win8系统好用吗,本文教您怎样运用U盘重装win8系统
- 硬盘分区工具,本文教您怎样给电脑硬盘分区
- u盘打开不了,本文教您u盘打开不了怎样修好
- windows7系统安装,本文教您win7系统怎样运用U盘安装
- u盘打开盘制作,本文教您如何迅速制作一个PE系统