前一節有提到在 .NET Core MVC 的專案中,會使用到的middleware 為EndpointMiddleware,與使用此middleware前會有那些準備事項。
這節會描述 .NET Core 如何安排與執行 middleware。通常我們會在專案的 Startup.Configure 中指定middleware的順序,然後以 ApplicationBuilder 的UseMiddleware方法來使用。
假設middleware的類別叫做 "MiddlewareClass" , 我們指定的方式則是:
builder.UseMiddleware<MiddlewareClass>();
下圖是呼叫 builder.UseMiddleware 的進入點:
步驟S1,當開始指定middleware,呼叫 ApplicationBuilder .UseMiddleware
。接著將 “MiddlewareClass” 的類別 Type 傳至 ApplicationBuilder.Use,此時會將此Type放入 Common Middleware Delegate Function,然後存放到ApplicationBuilder._Components委派函式集合。此委派函式的工作是將整個指定的middleware 串聯起來。
當準備好Common Middleware Delegate Function 後,接下來步驟S2執行ApplicationBuilder.Build,開始進行串聯middleware,也就是步驟S3。一開始會準備一個RequestDelegate app,此委派函式app是最後執行完開發者所指定的middleware後要做的最後工作。
接著,將ApplicationBuilder._Components做反轉排序,由最後一個開始往前串接,執行串接的工作就是剛剛準備好的 Common Middleware Delegate Function。串接一開始會找 “MiddlewareClass” 的類別中的 "Invoke” 或 "InvokeAsync” 的函式資訊,收集好後再由ServiceProviderEngineScope.GetService 來進行 “MiddlewareClass”類別的實例新增,再將此實例與函式資訊組合成一個像剛剛app一樣的委派,委派的內容就是未來要呼叫此類別的Invoke(InvokeAsync)函式。而委派的參數都是HttpContext Type。
下一輪處理另一個“MiddlewareClass” 類別的方式就是用剛剛組合好的app委派再處理一次。 可以看到上圖右下方區塊所示意最終的執行方式。
把此示意單獨擷取如下圖:
如上圖所示,最剛開始的 RequestDelegate app委派函式是被安排到最後執行。第一個委派函式為 "Meddleware[0]"。
下圖是接續工作:
步驟S4,新增 HostingApplication 實例,將串接好的middleware委派第一個委派函式 "Meddleware[0]” 指定到 HostingApplication._application上,傳送此HostingApplication實例到 IISHttpServer.StartAsync 中執行。
以上概述 .NET Core 在處理 Middleware 的過程,大致上可以知道執行的順序仍為開發者在 Startup.Confugure 中所安排的順序。要注意的是所有的委派都是 RequestDelegate 類型,其函式參數都是 HttpContext Type。