上一節我們描述了Middleware 在 .Net Core 是如何運作的,這節要來看如何由 Http Request 發送至.Net Core 的MVC中,產生 Controller的過程。
下圖為當透過URL發Request至.Net Core ,要到MVC時怎麼運作:
左上方是透過有MVC Controller與Action的URL 發送至 Dot Net Core Host。它會執行的middleware會是EndpointMiddleware.Invoke。而透過Routing組件的轉譯後,會產生HttpContext物件,這邊稱作 DefaultHttpContext。在EndpointMiddleware.Invoke,會去找到ActionEnpointFactory由CreateRequestDelegate所產生的委派函式,然後會執行DefaultHttpContext的擴充方法 GetEndpoint 會產生 RouteData、Endpoint、 ActionDescriptor 物件,分別指派到 ActionContext的 RouteData、HttpContext與ActionDescriptor屬性。
ActionContext 收集Request資訊與相關物件準備後,會被傳送到 ActionInvokerFactory.CreateInvoker 函式中。
ActionContext被傳送到 ActionInvokerFactory.CreateInvoker 函式,再被指派到ActionInvokerProviderContext.ActionContext。接著傳送到 ControllerActionInvokerProvider.OnProvidersExecuting,進一步產生ControllerContext實體,並讓所繼承的父類別完整複製ActionInvokerProviderContext.ActionContext。
接續找到 ControllerActionInvokerProvider._controllerActionInvokerCache,即ControllerActionInvokerCache,執行GetCachedResult。
GetCachedResult 函式 會找到 static class FilterFactory,其中有幾個FilterItem: UnsupportedContentTypeFilter、ClientErrorResultFilter、ModelStateInvalidFilter、ApiControllerAttribute。
這些FilterItem會包裝到FilterProviderContext.Results,FilterProviderContext.ActionContext也被指派ControllerContext,整個FilterProviderContext實例會傳到ControllerActionInvokerCache._filterProviders (即 DefaultFilterProvider) 的OnProvidersExcuted 與 OnProvidersExcuting 執行。
這邊有一個重要一提的是,ControllerFactoryProvider為之前就被DI出來過的instance,它是singleten,被指派到ControllerActionInvokerCache._ControllerFactoryProvider。
最後ControllerActionInvokerCache._currentCache 轉換成ControllerActionInvokerCacheEntry,回傳新增的 ControllerActionInvokerCacheEntry 物件與 FilterItem。
ControllerActionInvokerCache回傳新增的 ControllerActionInvokerCacheEntry 物件與 FilterItem集合物件後,接續新增ControllerActionInvoker物件,將ControllerContext 指派到ControllerActionInvoker._controllerContext 與 ControllerActionInvoker._actionContext。ControllerActionInvokerCacheEntry則指派到ControllerActionInvoker._cacheEntry,FilterItem集合物件指派到ControllerActionInvoker._filters。
下圖是接續執行ControllerActionInvoker.InvokeAsync:
依照上圖S1 到 S4步驟,會執行到ControllerActionInvoker._cacheEntry的ControllerFactory,其實就是ControllerActionInvokerCacheEntry的ControllerFactory,會執行由 ControllerFactoryProvider 經由其 CreateControllerFactory所產生的委派函式,透過ControllerContext物件參數取得controller Type,讓 ServiceProviderEngineScope.GetService 來取得實例。 ServiceProviderEngineScope.GetService 可以參考 "[Dot Net Core圖解] 4.實際如何實行DI Resolve Service"。
取得Controller實例後,會接續由Action的資訊來呼叫 action 函式,最後產生 ActionResult這邊後續有機會再詳述其過程。
以上為由Http發Request送到 Dot Net Core Host 後產生對應controller instance的概述,供整個大致流程參考。