但願給你3-5分鐘的碎片化學習,多是坐地鐵、等公交,聚沙成塔,水滴石穿,謝謝關注。git
要了解管道的實現機制,咱們必需要深刻框架的源碼,幸好微軟開源了,咱們能夠訪問GitHub的地址來下載源碼。github
git clone後,咱們打開工程,進入Microsoft.AspNetCore.Http項目搜索ApplicationBuilder類(以下圖),RequestDelegate是中間件的核心,而ApplicationBuilder是接收多個RequestDelegate的集合,因此解析ApplicationBuilder是瞭解整個管道實現的重要內容。而ApplicationBuilder裏有兩個重要的方法Build和Use也是咱們關注的焦點。app
咱們看下Use方法的參數是一個委託,該委託接收一個RequestDelegate參數,返回一個RequestDelegate,而_components.Add(middleware);是什麼呢?咱們看下這個全局變量的定義:框架
_components就是一個IList列表容器,也就是說Use方法作的事情很是簡單,就是不斷的把中間件middleware往容器裏面加而已,而中間件是什麼?就是一個由RequestDelegate構成的委託罷了。 學習
咱們知道Use還有一個重載方法,他是一個擴展方法,能夠在UseExtensions找到(以下圖),這個擴展方法其實也是調用上面的Use方法,往容器添加內容。測試
包括Run方法和上面相似,都是往容器灌入Middleware中間件。ui
Use完了以後,接下來作什麼呢?咱們看下Build實現代碼。spa
這裏對RequestDelegate集合進行反轉,而後逐一調用執行,因此app會被最後一個執行。最後只返回一個RequestDelegate code
接下來,咱們來模擬管道的構建過程,咱們先建兩個類,一個是RequestDelegate.cs和HttpContext.cs。component
HttpContext.cs咱們假設沒有任何實現:
RequestDelegate.cs定義一個委託
由於是模擬,因此咱們這裏使用控制檯來測試,dotnet new console --name iConsole
咱們在Program.cs實現核心代碼以下:
using System; using System.Collections.Generic; using System.Threading.Tasks; namespace iConsole { class Program { private static readonly IList<Func<RequestDelegate, RequestDelegate>> _mycomponents = new List<Func<RequestDelegate, RequestDelegate>>(); static void Main(string[] args) { //如下是Lambada表達式的簡寫 Use(next => { return context => { Console.WriteLine("PipeLine 1……"); return next.Invoke(context); }; }); Use(next => { return context => { Console.WriteLine("PipeLine 2……"); return next.Invoke(context); }; }); RequestDelegate PipeLine_end = context => { Console.WriteLine("PipeLine_end……"); return Task.CompletedTask; }; foreach (var component in _mycomponents) { PipeLine_end = component(PipeLine_end); } PipeLine_end.Invoke(new HttpContext()); Console.ReadLine(); } public static void Use(Func<RequestDelegate,RequestDelegate> middleware) { _mycomponents.Add(middleware); } } }
dotnet run後效果以下,整個模擬過程結束,是否是很簡單呢。
以上代碼大部分是截圖,截圖看起來更加順眼,雖然不方便複製,若是你想看完整代碼能夠訪問個人GitHub地址
但願以上分享對你有幫助,我是IT人張飛洪,入行10年有餘,人不堪其憂,吾不改其樂,謝謝您關注