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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Zato入门part2

    Zato入门part2

    2022年3月12日
    42
  • MVC-Chart_WebGrid 显示漂亮chart「建议收藏」

    MVC-Chart_WebGrid 显示漂亮chart「建议收藏」原文:http://www.tuicool.com/articles/maQrYnDemo_Chart_WebGridTwo Part:(1) design a table for test, create a view or procedure and input some records for test.(2) use the view or procedur

    2022年9月1日
    2
  • Logistic 回归算法原理[通俗易懂]

    Logistic 回归算法原理[通俗易懂]Logistic回归算法原理Sigmoid函数概率决策分布函数函数求导逻辑回归模型概率预测函数对数几率回归条件概率分布极大似然估计似然函数对数似然对数损失梯度上升Logistic回归,又名逻辑回归,它从线性回归发展而来,是一种广义的线性回归模型;该模型预测输出的是样本类别的条件概率分布,因而可以取概率值最大的类别作为分类结果,实质上是一个分类模型。Sigmoid函数概率决策首先来看一个实际应用场景下的分类问题:某电商网站有着大量的商品,当用户看到这些商品时,有两个选择,一是点击,二是不点击。

    2022年8月21日
    4
  • 宽度学习(Broad Learning System)

    宽度学习(Broad Learning System)宽度学习系统(BLS)一词的提出源于澳门大学科技学院院长陈俊龙于2018年1月发表的《BroadLearningSystem:AnEffectiveandEfficientIncrementalLearningSystemWithouttheNeedforDeepArchitecture》

    2022年5月22日
    33
  • debug灯在哪_shutterbug

    debug灯在哪_shutterbug

    2022年8月20日
    4
  • A星算法详解(个人认为最详细,最通俗易懂的一个版本)「建议收藏」

    A星算法详解(个人认为最详细,最通俗易懂的一个版本)「建议收藏」A*寻路算法原文地址:http://www.gamedev.net/reference/articles/article2003.asp概述虽然掌握了A*算法的人认为它容易,但是对于初学者来说,A*算法还是很复杂的。搜索区域(TheSearchArea)我们假设某人要从A点移动到B点,但是这两点之间被一堵墙隔开。如图1,绿色是A,红色是B

    2022年6月29日
    21

发表回复

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

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