【ASP.NET Core快速入門】(八)Middleware管道介紹、自己動手構建RequestDelegate管道


中間件是匯集到以處理請求和響應的一個應用程序管道的軟件。 每個組件:

  • 可以選擇是否要將請求傳遞到管道中的下一個組件。
  • 之前和之后調用管道中的下一個組件,可以執行工作。

使用請求委托來生成請求管道。 請求委托處理每個 HTTP 請求。

請求中使用委托來配置運行映射,和使用擴展方法。 一個單獨的請求委托,它可將指定的在行作為匿名方法 (稱為中,線中間件),或可以在可重用的類中定義它。 這些可重用的類和行在匿名方法中間件,或中間件組件。 在請求管道中的每個中間件組件負責調用管道中的下一個組件,或如果相應短路鏈。

使用 IApplicationBuilder 創建中間件管道

ASP.NET 核心請求管道由請求委托,調用一次是在另一個,如圖所示 (執行如下所示的黑色箭頭的線程) 的順序組成:

 

我們可以鏈接多個請求委托連同app.use。 next參數表示管道中的下一步委托。我們一共有兩種辦法構建管道:

然后執行dotnet build生成項目后執行 dotnet run 來運行我們我們的程序

 

 如果我們在第二步的時候不調用Invoke會怎樣?我們先執行 dotnet watch run

然后 我們再修改代碼:

IApplicationBuilder是用來構建管道的,我們可以通過Use來注冊中間件,同時可以傳遞給我們一個next的Deletegate的委托。在這個情況下,我們可以調用下一步中間件的委托,如果我們不調用的話,后面的管道就終止了。

還有一點就是IApplicationBuilder會提供給我們一個Map,我們可以理解為路由的機制。

我們后面的路由也是在這個基礎上進行配置的。運行效果:

自己動手構建RequestDelegate管道

什么是RequestDelegate

ASP.NET Core的中間件通過一個類型Func<RequestDelegate, RequestDelegate>的委托對象來表示,而RequestDelegate也是一個委托,它代表一項請求處理任務。

每個中間件都承載着獨立的請求處理任務,它本質上也體現了在當前HttpContext下針對請求的處理操作,那么為什么中間件不直接通過一個RequestDelegate對象來表示,而是表示為一個類型為Func<RequestDelegate, RequestDelegate>的委托對象呢?原因很簡單,中間件並不孤立地存在,所有注冊的中間件最終會根據注冊的先后順序組成一個鏈表,每個中間件不僅僅需要完成各自的請求處理任務外,還需要驅動鏈表中的下一個中間件。

對於一個由多個Func<RequestDelegate, RequestDelegate>對象組成的中間鏈表來說,某個中間件會將后一個Func<RequestDelegate, RequestDelegate>對象的返回值作為輸入,而自身的返回值則作為前一個中間件的輸入。某個中間件執行之后返回的RequestDelegate對象不僅僅體現了自身對請求的處理操作,而是體現了包含自己和后續中間件一次對請求的處理。那么對於第一個中間件來說,它執行后返回的RequestDelegate對象實際上體現了整個應用對請求的處理邏輯。

模擬RequestDelegate

首先先用VSCode新建一個控制台項目:MyPipeline,然后打開

dotnet new console --name MyPipeline

新建一個Context.cs類

using System;
using System.Threading.Tasks;

namespace MyPipeline
{
    public class Context
    {
        
    }
}

新建一個RequestDelegate.cs類

using System;
using System.Threading.Tasks;

namespace MyPipeline
{
    public delegate Task RequestDelegate(Context context);
}

在Program.cs中聲明一個接收委托、返回委托的List,並初始化

public static List<Func<RequestDelegate,RequestDelegate>> _list=new List<Func<RequestDelegate,RequestDelegate>>();
模擬ApplicationBuilder中的app.Use方法
        //模擬ApplicationBuilder中的app.Use方法
        public static void Use(Func<RequestDelegate,RequestDelegate> middleware)
        {
            _list.Add(middleware);
        }

在Main中調用

        static void Main(string[] args)
        {

            //第一步
            Use(next=>{
                return context=>{
                    System.Console.WriteLine("1");
                    return next.Invoke(context);
                    //return Task.CompletedTask;
                };
            });
            //第二步
            Use(next=>{
                return context=>{
                    System.Console.WriteLine("2");
                    return next.Invoke(context);
                };
            });

            RequestDelegate end=(context)=>{
                System.Console.WriteLine("end...");
                return Task.CompletedTask;
            };

            _list.Reverse();

            foreach(var middleware in _list)
            {
                end=middleware.Invoke(end);
            }

            //這時候我們沒有Context,所以直接new一個Context給它
            end.Invoke(new Context());

            Console.ReadLine();
        }

結果:

這個時候我們在第一步進行終止操作:

結果:

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM