希望給你3-5分鐘的碎片化學習,可能是坐地鐵、等公交,積少成多,水滴石穿,謝謝關注。
管道流
瞭解管道流機制,就能知道如何利用管道進行攔截,自定義封裝等高級操作,所以學習管道流機制對我們編碼有質的提高。那麼管道數據是如何流通的呢?如下圖所示,Request進入管道Middleware 1,疊加一層邏輯代碼到HttpContext(切確說是HttpContext的Response對象),然後調用next()進入到下一個管道Middleware 2,依次遞推,最後所有的邏輯代碼疊加完畢後返回前端。
管道實踐
實現自定義管道有兩種方法,使用IApplicationBuilder的Use和Run方法,他們的區別在下面會談到。
<strong>app.Use方法
這裡先了解Use方法的第一個重載,如下圖所示,他是一個類型為委託的中間件(middleware)。
這個中間件同時攜帶一個next的RequestDelegate委託,可以實現調用下一個管道中間件,我們看下代碼實踐,如下所示,context從當前管道進來,處理後,通過next.Invoke()轉移到下一個管道,完成一個管道的生命週期。
以上的用法,如果是新手可能不知其所以然,用沒問題,但是內部是如何實現的?不知道!其實這裡使用到了語言的高級特性委託,通過委託實現了開閉原則,也就是把管道的擴展開放出來,我們可以使用規定的app.Use方法,但是內部定義的委託參數類型,比如context,Fun
app.Use還有另外一個重載,如下圖提示:這裡Func傳入一個RequestDelegate,返回一個RequestDelegate。不同於第一個重載,他沒有next.Invoke()的調用,而是之間返回一個RequestDelegate給app進行處理。
我們看下代碼實現,外層紅色框是傳入的管道,內部綠色框是返回的管道。
<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方法放在所有管道的最後。
閱讀更多 IT人張飛洪 的文章