目录
在 Aps.net mvc 应用中对请求的处理最终都是转换为对某个 Controller 中的某个 Action 方法的调用,因此,要对一个请求进行处理,第一步,需要根据请求解析出对应的 Controller 和 Action 的名称,这是 Asp.net mvc 中的路由 的职责所在,第二步,需要根据第一步解析出来的内容定位对请求进行处理的 Action 方法所属的 Controller 类型,定位的过程称为 Asp.net mvc 中 Controller 的激活,第三步,就是根据请求的的内容到第二步定位的 Controller 中查找最终用来处理请求的 Action 方法并执行。
要执行一个方法,首先要根据方法签名从多个重载(如果有)中选出最为匹配的一个,然后对方法的参数进行绑定,Action 方法的执行亦是如此。
这一篇主要介绍一下 Action 方法执行过程的一些关键的组件。
关键组件
ActionInvoker
在 Asp.net mvc 中的 Controller 类型是指那些直接或间接的实现了 IController
接口的类型,在该接口中仅定义了一个 void Execute(RequestContext requestContext)
方法,在通过 Controller 的激活过程成功创建 Controller 类型的实例后,后续的 Action 方法的执行便是由该方法来执行的,该方法是一个同步的方法,但默认情况下,创建 Controller 实例后的后续操作是异步实现的,这些异步的操作是通过 IAsyncController
接口来实现的,该接口继承自 IController
,定义如下:
public interface IAsyncController : IController
{
IAsyncResult BeginExecute(RequestContext requestContext, AsyncCallback callback, object state);
void EndExecute(IAsyncResult asyncResult);
}
}
Action 方法的执行是通过 IActionInvoker 来实现的,该接口中只定义了一个 bool InvokeAction(ControllerContext controllerContext, string actionName)
方法,该接口同样具有一个异步的版本 IAsyncActionInvoker
,该接口继承自 IActionInvoker
,其定义如下:
public interface IAsyncActionInvoker : IActionInvoker
{
IAsyncResult BeginInvokeAction(ControllerContext controllerContext, string actionName, AsyncCallback callback, object state);
bool EndInvokeAction(IAsyncResult asyncResult);
}
}
具体使用同步还是异步的版本来执行 Action,如果 Controller 执行的是同步的 Execute(RequestContext requestContext)
方法,则便使用同步的 IActionInvoker,否则使用的是异步的 IAsyncActionInvoker
。
ActionInvoker 的创建
ActionInvoker 实例的创建是通过 Controller 类的 IActionInvoker CreateActionInvoker()
方法来创建的, IActionInvoker 的创建也是使用了 IOC 和工厂模式的思想,首先判断内部 IOC 容器(IDependencyResolver 类型)是否存在 IAsyncActionInvokerFactory类型的绑定,如果存在则创建该类型的实例,然后调用其 CreateInstance()
创建 IActionInvoker 类型的实例并返回,否则,判断 IOC 容器内是否存在 IActionInvokerFactory
类型的绑定,如果存在则创建该类型的实例,然后调用其 CreateInstance()
方法创建 IActionInvoker 类型的实例并返回。如果不存在,则判断 IOC 容器内是否存在 IAsyncActionInvoker 类型的绑定,如果存在,则创建实例并返回,否则判断是否存在 IActionInvoker 类型的绑定,如果存在,则创建实例并返回,如果不存在