从MvcHandler开始
首选MvcHandler显示实现了IHttpHandler接口中的void ProcessRequest(HttpContext context);
外层逻辑:
1.方法参数(context)类型的装换。(HttpContext类型->HttpContextBase类型)
HttpContext类是一个包含sealed修饰的类,不可再继承,如果MvcHandler里面处理请求的方式的参数为HttpContext类型,不考虑对Mvc其他功能模块的影响,从设计的角度来讲就已经违背了面向接口的编程方式。其实HttpContext类和HttpContextBase类里面的属性基本一样,我们去深入研究,大家可以去了解和反驳。
2.通过HttpContextBase类型的context去获取具体类型的Controller和ControllerFactory;
这里其实是一种IOC的思想,首先在MvcHandler的初始化方法(ProcessRequest)中定义两个分别接口类型为IController的控制器和IControllerFactory的控制器工厂。而真正能确定控制器和控制器真正类型是通过ProcessRequestInit(httpContext, out controller, out factory);反转到ControllerBuilder类中。
ControllerBuilder类负责IControllerFactory的创建。ControllerBuilder在创建的时候通过参数注入类接口类型为IResolver<IControllerFactory>的参数(serviceResolver)该接口唯一的成员就是Current;Current的注入是通过ControllerBuilder的静态属性Current获取到ControllerBuilder的实例,并且通过实例方法public void SetControllerFactory(IControllerFactory controllerFactory)或者 public void SetControllerFactory(Type controllerFactoryType)将自己继承与IControllerFactor接口的控制器工厂注入到ControllerBuilder中的静态属性Current中去。这就说明,我们必须在MvcHandler处理请求之前对Current属性进行注入(这不是废话..)。
3.好,上面两步大体的其实就是一些准备工作(通过Context以及注入的方式获取对应的工厂以及控制器)。我们要进入真正的处理环境了,看代码:
protected internal virtual void ProcessRequest(HttpContextBase httpContext)
{
IController controller;
IControllerFactory factory;
ProcessRequestInit(httpContext, out controller, out factory);
try
{
controller.Execute(RequestContext);
}
finally
{
factory.ReleaseController(controller);
}
}
很好理解,真正的执行在controller.Execute(RequestContext)方法中,以及执行完后通过控制器工厂释放当前控制器内存。注意:这种释放并非将整个控制器实例释放,控制器类中有定义一个结构体来避免有些不应该释放的资源。就说这么多,感觉这里多大家以后的编程,对Mvc的理解会更深层次一点。
内层逻辑:
真正关于controller.Execute(RequestContext);的执行结构会涉及到ControllerBase及Controller两个抽象类及三大Descriptor和Filters、Binds、Invoker、Cache、ActionResult等等,这方面的东西我会在以后全部解剖出来,讲解内容有什么问题,请各位不必吝啬提出来,非常感谢。