MVC4 Action 方法的执行

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. 默认创建的ActionInvoker
            yield 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 对象描述。

    

原文地址:https://www.cnblogs.com/dragon-L/p/5259917.html