4.5管道實現機制和模擬構建管道「深刻淺出ASP.NET Core系列」

但願給你3-5分鐘的碎片化學習,多是坐地鐵、等公交,聚沙成塔,水滴石穿,謝謝關注。git

管道實現機制

要了解管道的實現機制,咱們必需要深刻框架的源碼,幸好微軟開源了,咱們能夠訪問GitHub的地址來下載源碼。github

git clone後,咱們打開工程,進入Microsoft.AspNetCore.Http項目搜索ApplicationBuilder類(以下圖),RequestDelegate是中間件的核心,而ApplicationBuilder是接收多個RequestDelegate的集合,因此解析ApplicationBuilder是瞭解整個管道實現的重要內容。而ApplicationBuilder裏有兩個重要的方法Build和Use也是咱們關注的焦點。app

   

Use方法

  

  咱們看下Use方法的參數是一個委託,該委託接收一個RequestDelegate參數,返回一個RequestDelegate,而_components.Add(middleware);是什麼呢?咱們看下這個全局變量的定義:框架

  

   _components就是一個IList列表容器,也就是說Use方法作的事情很是簡單,就是不斷的把中間件middleware往容器裏面加而已,而中間件是什麼?就是一個由RequestDelegate構成的委託罷了。   學習

  咱們知道Use還有一個重載方法,他是一個擴展方法,能夠在UseExtensions找到(以下圖),這個擴展方法其實也是調用上面的Use方法,往容器添加內容。測試

  

  包括Run方法和上面相似,都是往容器灌入Middleware中間件。ui

  

Build方法

   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年有餘,人不堪其憂,吾不改其樂,謝謝您關注

相關文章
相關標籤/搜索