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

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

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之前的部分粗略的讲解一下,请先看如下图:

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

 

如上图,这里先要说的是控制器类型缓存对象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部分之后的实现概念图:

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

获取到了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的一个过程图:

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

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

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

 

 

 

 

作者:金源

出处:http://www.cnblogs.com/jin-yuan/

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面

转载于:https://www.cnblogs.com/jin-yuan/p/3779004.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/109806.html原文链接:https://javaforall.net

(0)
上一篇 2021年8月30日 上午6:00
下一篇 2021年8月30日 上午7:00


相关推荐

  • Java Object转JSONObject,ArrayList,取值

    Java Object转JSONObject,ArrayList,取值Java 中 Object 转 JSONObject JSONObjectjs JSONObject JSONObject toJSON list get 0 Java 中 Object 转化为 ArrayListLis Object list List Object objJava 中获取 Object 中的值的方法例 Objectobject name 张三 age 23 代码实现 Mapentity Map object Object Object

    2026年3月17日
    2
  • iterator的用法_名词所有格的用法整理初一

    iterator的用法_名词所有格的用法整理初一@Overrideprotectedvoidreduce(Textkey,Iterable<IntWritable>values,Contextcontext)throwsIOException,InterruptedException{intcount=0;Iterator<IntWritable>iterator=values.iterator();//<1,1,1>

    2025年8月4日
    7
  • idea 集成svn_idea怎么关联svn

    idea 集成svn_idea怎么关联svn当你idea集成svn工具时:依照如下步骤:1.下载并安装svn:链接:https://pan.baidu.com/s/1jIs00Pg密码:2o3x2.特别说明:如果你没选上:那么你会在你的安装路径上无法找到svn.exe3.之后你就可以正常的使用svn。

    2022年10月17日
    6
  • 再见PowerDesigner,这款国人开源的数据库设计工具Chiner真香

    再见PowerDesigner,这款国人开源的数据库设计工具Chiner真香再见PowerDesigner,这款国人开源的数据库设计工具Chiner真香当我们在项目开发初期时,往往需要设计大量的表,此时使用数据库设计工具就会比较高效!今天给大家推荐一款国人开源的数据库设计工具chiner,界面漂亮,功能强大,希望对大家有所帮助!回顾PowerDesigner相信平时工作中,大家或多或少会使用PowerDesigner来设计数据库,感觉这款工具界面有点古老,界面看着就具年代感,有时候用起来也比较重,来看下之前使用它设计数据库的效果。最近体验了一把chiner,设计数据库

    2022年7月27日
    11
  • 9.关于Unicode字符集

    9.关于Unicode字符集原文链接 http blog csdn net yang3wei article details 点击阅读原文 1 Java nbsp 中 char 占两个字节 既可以表示中文字符 也可以表示英文字符 2 Unicode 只是一个编码规范 目前实际实现的 unicode 编码只要有三种 UTF 8

    2026年3月19日
    2
  • codeforces Arrival of the General 题解

    codeforces Arrival of the General 题解

    2022年1月31日
    41

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号