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

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

  • 能夠選擇是否要將請求傳遞到管道中的下一個組件。
  • 以前和以後調用管道中的下一個組件,能夠執行工做。

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

請求中使用委託來配置運行映射,和使用擴展方法。 一個單獨的請求委託,它可將指定的在行做爲匿名方法 (稱爲中,線中間件),或能夠在可重用的類中定義它。 這些可重用的類和行在匿名方法中間件,或中間件組件。 在請求管道中的每一箇中間件組件負責調用管道中的下一個組件,或若是相應短路鏈。ui

使用 IApplicationBuilder 建立中間件管道

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

 

咱們能夠連接多個請求委託連同app.use。 next參數表示管道中的下一步委託。咱們一共有兩種辦法構建管道:線程

而後執行dotnet build生成項目後執行 dotnet run 來運行咱們咱們的程序3d

 

 若是咱們在第二步的時候不調用Invoke會怎樣?咱們先執行 dotnet watch runcode

而後 咱們再修改代碼:中間件

IApplicationBuilder是用來構建管道的,咱們能夠經過Use來註冊中間件,同時能夠傳遞給咱們一個next的Deletegate的委託。在這個狀況下,咱們能夠調用下一步中間件的委託,若是咱們不調用的話,後面的管道就終止了。對象

還有一點就是IApplicationBuilder會提供給咱們一個Map,咱們能夠理解爲路由的機制。blog

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

本身動手構建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();
        }

結果:

這個時候咱們在第一步進行終止操做:

結果:

相關文章
相關標籤/搜索