.net core 中间件到底是如何执行
本篇是在下对中间件执行逻辑的一点理解,有不对的地方欢迎大佬指出,小的感激不尽
根据一些资料写了一些模拟方法,对应原生代码去掉My,可以先看看代码
static void Main(string[] args) { { IMyApplicationBuilder builder = new MyApplicationBuilder(); builder.Use(next => { return new MyRequestDelegate(context => { Console.WriteLine("01开始"); next.Invoke(context); Console.WriteLine("01结束"); }); }); builder.Use(next => { return new MyRequestDelegate(context => { Console.WriteLine("02开始"); next.Invoke(context); Console.WriteLine("02结束"); }); }); builder.Use(next => { return new MyRequestDelegate(context => { Console.WriteLine("03开始"); //next.Invoke(context); 这里因为到最后了,不需要再invoke了,再invoke的话就进入到我们预定义的那个MyRequestDelegate里了 Console.WriteLine("03结束"); }); }); MyRequestDelegate myRequestDelegate = builder.Build(); myRequestDelegate.Invoke(new MyHttpcontext()); } }
public interface IMyApplicationBuilder { MyRequestDelegate Build(); IMyApplicationBuilder Use(Func<MyRequestDelegate, MyRequestDelegate> middleware); } public delegate void MyRequestDelegate(MyHttpcontext context); public class MyHttpcontext { }
public class MyApplicationBuilder : IMyApplicationBuilder { private static List<Func<MyRequestDelegate, MyRequestDelegate>> funcs = new List<Func<MyRequestDelegate, MyRequestDelegate>>(); public MyRequestDelegate Build() { MyRequestDelegate myRequestDelegate = context => { }; funcs.Reverse(); foreach (var item in funcs) { myRequestDelegate = item.Invoke(myRequestDelegate); } return myRequestDelegate; } public IMyApplicationBuilder Use(Func<MyRequestDelegate, MyRequestDelegate> middleware) { funcs.Add(middleware); return this; } }
执行逻辑
//1.拼装一个拥有入参和出参相同都为委托requestDelegate的一个委托list出来,(app.use的时候就是拼装list的时候)
//2.builder.Build() 反转这个list 这里可能不明白没关系 这个只影响最后运行的顺序
//3.定义一个委托requestDelegate,因为执行list里面的委托需要一个requestDelegate的参数,循环这个委托list,循环里invoke委托,invoke委托需要一个requestDelegate,将这个定义的委托放进去,又得到 一个新的requestDelegate作为下一次循环的参数 (注意这里套娃开始了),让我们来看看invoke之后发生了什么,随着第一个委托invoke,我们定义的第一个requestDelegate委托参数传了进去,然后又返回一个requestDelegate,如果我们把传进去的这个委托在返回的这个requestDelegate内部invoke,这不就意味着我们得到了一个在我们定义的这个委托基础上外层又加了些逻辑的委托吗,因为得到的这个委托将作为参数执行下一次的invoke,然后又返回一个在此前面基础上又增加了逻辑的委托,那么最终循环完这个list,我们得到一个层层嵌套委托的委托。
//4.将这个层层嵌套委托的委托invoke,那么就会从最外层开始执行,执行到中间发现第二个委托,进入第二个委托执行代码,就这样执行到最里面,当最后一个requestDelegate执行完,则会层层往外执行,直到第一个委托执行完