1. 程式人生 > >.NET CORE 中介軟體

.NET CORE 中介軟體

## 什麼是中介軟體 ## 對於中介軟體我們其實並不陌生,在.NET CORE出現之前中介軟體的概念在OWIN應用程式中就已經普遍使用了。 中介軟體官方定義: 中介軟體是一種整合到應用管道中間來處理請求和響應的模組,每個中介軟體可以: - 選擇是否將請求傳遞到管道的下一個元件 - 可以在管道的下一個元件前後執行工作 ASP.NETCORE中的中介軟體本質上是一個請求委託 `Func< RequestDelegate, RequestDelegate> middleware`。 RequestDelegate本身也是一個委託,定義為 `public delegate Task RequestDelegate(HttpContext Context)`。 在ASP.NETCORE請求管道中,形成一條委託鏈。 ![委託鏈](https://img2020.cnblogs.com/blog/365548/202006/365548-20200604105209232-842964941.png) 請求管道短路:當委託不選擇將請求傳遞到下一個委託時,稱之為“短路”。 ## 如何建立中介軟體 ## 在ASP.NETCORE中,使用 `IApplicationBuilder` 來建立/插入中介軟體管道。提供了 **Run**和**Use** 兩類方式。依賴元件包 `Microsoft.AspNetCore.Http.Abstractions` Run是一種 **約定** 的終端管道,即短路,不再執行下一個委託 public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.Run(async context => { await context.Response.WriteAsync("hello world 1"); }); //這裡不會執行到!! app.Run(async context => { await context.Response.WriteAsync("hello world 2"); }); } Use通常以擴充套件方法提供中介軟體,很適合處理一些AOP的事務。 public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.Use(async (context, next) => { //可以在invoke之前做一些事 await next.Invoke(); //可以在invoke之後做一些事 }); app.Run(async context => { await context.Response.WriteAsync("hello world"); }); } 實際開發中我們通常需要自己定義中介軟體,有兩種方式可以實現。 ### 約定方式 ### public class RequestIdInRequestMiddleware { private readonly RequestDelegate _next; public RequestIdInRequestMiddleware(RequestDelegate next) { _next = next; } public Task Invoke(HttpContext httpContext,IService service) { service.SayHello(); //request head 加入requestid var requestId = Guid.NewGuid().ToString("n"); httpContext.Request.Headers.Add("REQUESTID", requestId); return _next(httpContext); } } 如上有以下約定: - 具有型別為 `RequestDelegate` 的引數公共建構函式 - 名為 `Invoke` 或 `InvokeAsync` 的公共方法,且此方法必須: - 返回 `Task` - 第一個引數為 `HttpContext` 目前官方是推薦使用約定方式, **注意**:該方式加入管道中的生命週期為**單例**。也因此如果依賴一些Service,建議從`Invoke` 或 `InvokeAsync`的方法引數注入,而不是從建構函式注入。(可以想想為什麼?單例建構函式注入對Service的生命週期有要求~~)。 ### 強型別 ### 官方也提供了IMiddleware介面,用於擴充套件建立中介軟體。這種方式有兩個優點: - 可以按需(生命週期)注入 - 中介軟體強型別話,更易理解 public class RequestIdInResponseMiddleware:IMiddleware { private readonly IService _service; public RequestIdInResponseMiddleware(IService service) { _service = service; } public Task InvokeAsync(HttpContext context, RequestDelegate next) { var requestId = Guid.NewGuid().ToString("n"); context.Response.Headers.Add("REQUESTID", requestId); return next(context); } } ### 中介軟體加入管道 ### 中介軟體一般都是基於IApplicationBuilder擴充套件方法加入管道。 public static class RequestIdMiddlewareExtensions { public static IApplicationBuilder UseRequestIdInResponseMiddleware(this IApplicationBuilder builder) { return builder.UseMiddleware