1. ActionInvoker 的執行:
在MVC 中 ?包括Model綁定與驗證在內的整個Action的執行是通過一個名為ActionInvoker的組件來完成的。 它同樣具有 同步/異步兩個版本。
? ? ?分別實現了接口 IActionInvoker /IAsyncActionInvoker。
? ? ?ASP.NET MVC 中真正用于Action方法同步和異步執行ActionInvoker 類型分別是 ContorllerActionInvoker /AsyncContollerActionInvoker.
? ? ?AsyncContollerActionInvoker 是?ContorllerActionInvoker ?的子類
? ? ?也就是說 當Action 沒有指定 ?實現?IActionInvoker /IAsyncActionInvoker 接口的時候 ?它默認是 執行AsyncContollerActionInvoker 的.
? ? 我們來看下面的代碼片段:
? ? 我們通過?Ninject 對?SyncActionInvoker 和?AsyncActionInvoker 進行接口的映射,然后創建一個?ActionInvoker?
? ? 其返回的結果分別是 ?各自的實例對象?AsyncContollerActionInvoker?SyncActionInvoker ?AsyncActionInvoker (這中間有一個前提需要進行 緩沖的清除 )
? ??
?
public ActionResult Index(){return View(this.GetActionInvokers().ToArray());}public IEnumerable<IActionInvoker> GetActionInvokers(){//Current 代表的是當前DependencyResolver。NinjectDependencyResolver dependencyResolver = (NinjectDependencyResolver)DependencyResolver.Current;//1. 默認創建的ActionInvokeryield return this.CreateActionInvoker();//2. 為Dependency注冊針對IActionInvoker的類型映射 dependencyResolver.Register<IActionInvoker, SyncActionInvoker>();yield return this.CreateActionInvoker();//3. 為Dependency注冊針對IAsyncActionInvoker的類型映射dependencyResolver.Register<IAsyncActionInvoker, AsyncActionInvoker>();yield return this.CreateActionInvoker();}
? ?注意: 創建 ActionInvoker 的3個步驟
? ?1.) 在創建?CreateActionInvoker 的時候 如果返回 不為null 則將其默認為ActionInvoker, 也就是如上代碼,(清除ActionInvoker緩存后) 它返回 ? ? ? ? ? ? ? ? ? ? ? ?AsyncContollerActionInvoker, 如果 返回null ?則進入 下一步驟。
? 2.) 創建 IActionInvoker ?規則同上
? 3.)創建?IAsyncActionInvoker?規則同上
?
?2. ControllerDescriptor 的同步/異步
如果Controller使用ControllerActionInvoker ,它所有的Action總是以同步方式執行。
? ? ? 如果 Controller使用AsyncControllerActionInvoker 作為ActionInvoker時,卻并不意味這總是異步方式。
? ? ? 通過兩個描述對象?ControllerDescriptor ?和?ActionDescriptor?
? ? ? 在默認情況下?ReflectedControllerDescriptor ?是通過ControllerActionInvoker 來創建的。
? ? ? ReflectedAsyncControllerActionInvoker 是通過AsyncControllerActionInvoker ?來創建的。
? ? ? 看如下代碼 他們返回 返回的值 分別是對象類型的 ?ReflectedControllerDescriptor ? 和?ReflectedAsyncControllerActionInvoker 。
public class SyncActionInvoker : ControllerActionInvoker{public new ControllerDescriptor GetControllerDescriptor(ControllerContext controllerContext){return base.GetControllerDescriptor(controllerContext);}}public class AsyncActionInvoker : AsyncControllerActionInvoker{public new ControllerDescriptor GetControllerDescriptor(ControllerContext controllerContext){return base.GetControllerDescriptor(controllerContext);}}
?
? ?3.ActionDescriptor的執行。
? ? ?Action 方法可以采用同步和異步執行方式,異步Action對應的ActionDescriptor 直接或者間接繼承自抽象類AsyncActionDescriptor,
? ? ?AsyncActionDescriptor 又是抽象類ActionDescriptor的子類。
? ? ?同步和異步的 Action 分別 調用 Execute 和 ?BeginExecute/EndExecute方法來完成
? ? ?AsyncActionDescriptor 重寫了Execute 會拋出異常,所以?AsyncActionDescriptor對象只能采用異步執行。
? ? 同步Action 通過ReflectedControllerDescriptor 對象描述。
? ? 異步Action 通過ReflectedAsyncControllerDescriptor ?對象描述。
? ? 返回Task的異步Action 則通過TaskAsyncControllerDescriptor 對象描述。
? ??
?