4.4管道Middleware簡介「深入淺出ASP.NET Core系列」

希望給你3-5分鐘的碎片化學習,可能是坐地鐵、等公交,積少成多,水滴石穿,謝謝關注。

管道流

瞭解管道流機制,就能知道如何利用管道進行攔截,自定義封裝等高級操作,所以學習管道流機制對我們編碼有質的提高。那麼管道數據是如何流通的呢?如下圖所示,Request進入管道Middleware 1,疊加一層邏輯代碼到HttpContext(切確說是HttpContext的Response對象),然後調用next()進入到下一個管道Middleware 2,依次遞推,最後所有的邏輯代碼疊加完畢後返回前端。

4.4管道Middleware簡介「深入淺出ASP.NET Core系列」

管道實踐

實現自定義管道有兩種方法,使用IApplicationBuilder的Use和Run方法,他們的區別在下面會談到。

<strong>app.Use方法

這裡先了解Use方法的第一個重載,如下圖所示,他是一個類型為委託的中間件(middleware)。

4.4管道Middleware簡介「深入淺出ASP.NET Core系列」

這個中間件同時攜帶一個next的RequestDelegate委託,可以實現調用下一個管道中間件,我們看下代碼實踐,如下所示,context從當前管道進來,處理後,通過next.Invoke()轉移到下一個管道,完成一個管道的生命週期。

4.4管道Middleware簡介「深入淺出ASP.NET Core系列」

以上的用法,如果是新手可能不知其所以然,用沒問題,但是內部是如何實現的?不知道!其實這裡使用到了語言的高級特性委託,通過委託實現了開閉原則,也就是把管道的擴展開放出來,我們可以使用規定的app.Use方法,但是內部定義的委託參數類型,比如context,Fun

則對外屏蔽了實現。所以你看到的next.Invoke()已經封裝了具體的實現了,對於使用者,其實可以不用去管那麼多,拿來用即可。

app.Use還有另外一個重載,如下圖提示:這裡Func傳入一個RequestDelegate,返回一個RequestDelegate。不同於第一個重載,他沒有next.Invoke()的調用,而是之間返回一個RequestDelegate給app進行處理。

4.4管道Middleware簡介「深入淺出ASP.NET Core系列」

我們看下代碼實現,外層紅色框是傳入的管道,內部綠色框是返回的管道。

4.4管道Middleware簡介「深入淺出ASP.NET Core系列」

<strong>app.Run

app.Run和app.Use不同之處在於,app.Use可以調用下一個中間件的管道,app.Run不會,我們演示一段代碼。

 app.Use(async (context, next) =>
{
await context.Response.WriteAsync("");
await context.Response.WriteAsync("
Inside middleware defined using app.Use
");
await next();
await context.Response.WriteAsync("");
});

app.Run(async context => {

await context.Response.WriteAsync("
Inside middleware defined using app.Run
");
});

 //該管道會不會被打印呢?
app.Use(async (context, next) =>
{
await context.Response.WriteAsync("");
await context.Response.WriteAsync("
Another Middleware defined using app.Use
");
await next();
await context.Response.WriteAsync("");
});

如下圖所示,我們看到Run後面定義的第二個Use沒有打印出來,這是因為Run不會調用隨後的管道導致的,所以我們一般習管性把Run方法放在所有管道的最後。

4.4管道Middleware簡介「深入淺出ASP.NET Core系列」

希望以上分享對你有幫助,我是張飛洪,入行10年有餘,人不堪其憂,吾不改其樂,謝謝您關注


分享到:


相關文章: