您的位置:首页 > 编程语言 > ASP

ASP.NET MVC 控制器激活(一)

2016-03-26 19:24 513 查看

ASP.NET MVC 控制器激活(一)

前言

在路由的篇章中解说了路由的作用,讲着讲着就到了控制器部分了,从本篇開始来解说MVC中的控制器,控制器是怎么来的?MVC框架对它做了什么?以及前面有的篇幅所留的疑问将会在这部分里解决掉。

对于控制器激活的总结

总的来说控制器的激活过程有这么几个步骤(部分):

1.依据当前路由信息获取控制器名称

2.获取当前系统的控制器工厂(用来生成控制器)

2.1 据控制器名称生成和当前系统的请求上下文參数生成控制器类型(Type)

2.1.1 依据当前的路由信息推断选择控制器所在命名空间

2.1.2 返回控制器类型(Type)

2.2 依据控制器类型(Type)请求上下文參数生成控制器类型(IController)

2.3 返回控制器类型(IController)

3.获取由控制器工厂生成的控制器(IController)

4.运行IController.Execute()

控制器的由来

前面都有讲到MVC的入口在Module中。详细是在注冊路由的时候,默认的注冊MvcHandler作为请求处理类型,而控制器的就是在这里生产出来的,为什么说是生产?由于系统预先实现了一个控制器工厂类DefaultControllerFactory(例如以下的代码结构),在控制器生成到运行的这个过程里涉及到众多的类型和控制器的对象模型,这些内容在后面篇幅会一一解说。

DefaultControllerFactory类型的结构:

1     public class DefaultControllerFactory : IControllerFactory
2     {
3         public DefaultControllerFactory();
4         public DefaultControllerFactory(IControllerActivator controllerActivator);
5
6         public virtual IController CreateController(RequestContext requestContext, string controllerName);
7         protected internal virtual IController GetControllerInstance(RequestContext requestContext, Type controllerType);
8         protected internal virtual SessionStateBehavior GetControllerSessionBehavior(RequestContext requestContext, Type controllerType);
9         protected internal virtual Type GetControllerType(RequestContext requestContext, string controllerName);
10         public virtual void ReleaseController(IController controller);
11     }


本篇先将上面总结中的2.1.2之前的部分粗略的解说一下。请先看例如以下图:



如上图,这里先要说的是控制器类型缓存对象ControllerTypeCache,ControllerTypeCache载入全部实现了IController接口的公共类并缓存在MVC-ControllerTypeCache.xml文件中。当然了这些都是框架所做的,我们仅仅需了解一下。学习当中的思想即可了。

在请求到达默认请求处理程序的时候,由默认的控制器工厂DefaultControllerFactory来依据RouteData的DataToken【NameSpaces】里的定义的命名空间和Values【controller】的控制器名称来进行推断,详细怎么推断的是由ControllerTypeCache对象来查询匹配的。

先依据控制器名称查询缓存中是否有相应此名称的控制器,假设有则存放在 ILookup<string, Type>类型对象中,然后依据RouteData的DataToken【NameSpaces】里的定义的命名空间来和ILookup<string, Type>对象中的控制器类型所在命名空间进行比对。假设是同样的则加入此类型到返回集合。假设不同样则继续用RouteData的DataToken【NameSpaces】剩下的命名空间值挨个的进行比对。

依据返回的类型集合,假设总数为0返回空,总数为1返回此集合中的类型,假设大于1则会引发CreateAmbiguousControllerException类型的异常。

在此时DefaultControllerFactory中已经获取到了控制器类型(Type)。

在总结中2.2所指部分为IControllerActivator接口类型的实现。

1     // 摘要:
2     //     对使用依赖项注入实例化控制器的方式进行精细控制。

3     public interface IControllerActivator
4     {
5         // 摘要:
6         //     在类中实现时创建控制器。
7         //
8         // 參数:
9         //   requestContext:
10         //     请求上下文。
11         //
12         //   controllerType:
13         //     控制器类型。
14         //
15         // 返回结果:
16         //     创建的控制器。

17         IController Create(RequestContext requestContext, Type controllerType);


这部分的实现。能够注入到控制器工厂,而实现的内部依旧有可扩展注入的地方。在MVC框架中有默认的实现,我们先来看一下2.2部分之后的实现概念图:



获取到了Controller的Type过后,DefaultControllerFactory就能够依据Type来创建Controller。然而在MVC框架的设计中。【依据ControllerType创建Controller的方式】是不会放在DefaultControllerFactory中的,而是通过MVC框架中实现了IControllerActivator接口类型的默认实现类DefaultControllerActivator类型来进行创建IController的。而在DefaultControllerActivator中又是通过DependencyResolver类型来创建一个IDependencyResolver接口的默认实现类来实现的。

在IDependencyResolver接口中,有个GetService()方法。这种方法就是终于要创建类型所用到的方式,也能够自己定义来实现,这也是扩展点之中的一个。

说回接口类型,MVC中有个默认的实现了IDependencyResolver接口的类型DefaultDependencyResolver,在DefaultDependencyResolver类型中GetService()方法的默认实现方式Activator.CreateInstance(serviceType);也就是正常通过反射来创建类型的。

看一下由Handler到Icontroller的一个过程图:



上面的这些以及前面篇幅所讲,都是MVC默认实现的方式。每一个部分都能够自己定义来扩展,MvcHandler、DefaultControllerFactory、DefaultDependencyResolver等等这些类型。

会在后面的篇幅中说明在激活控制器的过程中全部可注入扩展点的。

作者:金源

出处:http://blog.csdn.net/jinyuan0829

本文版权归作者和CSDN共同拥有,欢迎转载,但未经作者允许必须保留此段声明,且在文章页面
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: