Asp.NetCore 自定義中介軟體
這節演示一下自定義中介軟體,第一節我們講到,中介軟體的處理流程就像一個俄羅斯套娃,那這種俄羅斯套娃型的流程內部是如何實現的呢,下面請看程式碼。
第一種寫法是直接寫在Configure方法中的,使用app.Use(委託)配合lambda表示式使用,適合很輕量級的中介軟體。
app.Use(async (context, next) => { await context.Response.WriteAsync("CustomerMiddleWare1-in\n"); await next(); await context.Response.WriteAsync("CustomerMiddleWare1-out"); });
微軟約定中介軟體需要兩個引數,一個是httpcontext上下文物件,一個是Task型別的委託。通過上下文物件,處理請求,通過委託傳遞上下文物件到下一個中介軟體(這也是套娃模式的由來)。
這也限制了方法,必須是非同步的async方法,呼叫next()之後,上下文物件傳送給下一中介軟體了,該方法就會處於等待狀態,直到後續的中介軟體處理完畢,返回後,再執行next()方法之後的程式碼。(關於同步和非同步的有關知識,將在後續進行講解)
除了使用Use()方法,還有一種用法,這個方法有點特殊,因為它不存在next()方法傳遞上下文物件,它是請求管道的底,用於直接返回響應
//run 是終端中介軟體,他是沒有next()方法的,只要進入這個中介軟體,後續的中介軟體都不會執行了,從它這裡請求完畢原路返回 app.Run(async context => { await context.Response.WriteAsync("I am End MiddleWare\n"); });
.NetCore3.x推出了一個新的中介軟體,叫EndPoints
app.UseEndpoints(endpoints => { endpoints.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); });
它跟Run()一樣,是兜底的中介軟體,但是用法比較特殊了,微軟給我們的預設配置就是直接路由到某一頁面,一般是網站首頁。
下面看一下執行結果的演示,有如下三個中介軟體:
//use是新增中間中介軟體,就是處理完了,繼續傳給下一個中介軟體,它有next()委託 app.Use(async (context, next) => { await context.Response.WriteAsync("CustomerMiddleWare1-in\n"); await next(); await context.Response.WriteAsync("CustomerMiddleWare1-out"); }); app.Use(async (context, next) => { await context.Response.WriteAsync("CustomerMiddleWare2-in\n"); await next(); await context.Response.WriteAsync("CustomerMiddleWare2-out\n"); }); //run 是終端中介軟體,他是沒有next()方法的,只要進入這個中介軟體,後續的中介軟體都不會執行了,從它這裡請求完畢原路返回 app.Run(async context => { await context.Response.WriteAsync("I am End MiddleWare\n"); });
執行結果為:
這很直觀的反應了中介軟體的順序執行,以及巢狀執行
下面看一下如何定義一個真正的自定義中介軟體
首先,我們要明確,微軟規定的自定義中介軟體的要求
1.具有型別為RequestDelegate引數的公共建構函式,這個引數就是請求委託,它在一個個的中介軟體中傳遞
2.具有Invoke或者InvokeAsync的方法,該方法的返回值必須是Task,而且第一個引數必須是HttpContext
public class MyMiddleWare { private readonly RequestDelegate _next; public MyMiddleWare( RequestDelegate next ) { _next = next; } public async Task InvokeAsync(HttpContext context) { //此處寫中介軟體業務邏輯 //然後呼叫next指向下一個中介軟體 //呼叫next之前,屬於請求部分的處理 await _next(context); //next執行完畢之後,屬於相應部分的處理 } }
定義完成以後,使用UseMiddleware<中介軟體>()將自定義中介軟體新增進來
app.UseMiddleware<MyMiddleWare>();
但這樣的用法,還是少了一點優雅與靈活性,我們可以通過擴充套件方法的形式,為IApplicationBuilder新增擴充套件方法,實現自定義中介軟體新增與配置的靈活應用(擴充套件方法在之前的文章中有講)
public static class MyMiddleWareExtension { public static IApplicationBuilder UseMymiddleware(this IApplicationBuilder app) { return app.UseMiddleware<MyMiddleWare>(); } }
這樣的話,就可以直接呼叫方法新增中介軟體了
//使用擴充套件方法的形式,新增自定義中介軟體然後可以通過構造方法的形式,傳遞配置引數 app.UseMymiddleware();
初學者可對此做初步瞭解,對其中設計的程式碼語法知識,是必須要掌握的。另外,如果需要檢視ASP.NetCore的原始碼,請訪問https://github.com/dotnet/aspnetcore自行下載或克隆到本地
這是我公眾號二維碼,最新的文章會同步至此