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

如上图,这里先要说的是控制器类型缓存对象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等等这些类型。
会在后面的篇幅中说明在激活控制器的过程中所有可注入扩展点的。
MVC 控制器的更多相关文章
- ABP文档 - Mvc 控制器
文档目录 本节内容: 简介 AbpController基类 本地化 其它 过滤 异常处理和结果包装 审计日志 验证 授权 工作单元 反伪造 模型绑定器 简介 ABP通过nuget包Abp.Web.Mv ...
- ABP理论学习之MVC控制器(新增)
返回总目录 本篇目录 介绍 AbpController基类 本地化 异常处理 响应结果的包装 审计日志 授权 工作单元 其他 介绍 ABP通过Abp.Web.Mvc nuget包集成了ASP.NET ...
- ASP.NET MVC 控制器激活(一)
ASP.NET MVC 控制器激活(一) 前言 在路由的篇章中讲解了路由的作用,讲着讲着就到了控制器部分了,从本篇开始来讲解MVC中的控制器,控制器是怎么来的?MVC框架对它做了什么?以及前面有的篇幅 ...
- ASP.NET MVC 控制器激活(二)
ASP.NET MVC 控制器激活(二) 前言 在之前的篇幅中,用文字和图像来表示了控制器的激活过程,描述的角度都是从框架默认实现的角度去进行描述的,这样也使得大家都可以清楚的知道激活的过程以及其中涉 ...
- ASP.NET MVC 控制器激活(三)
ASP.NET MVC 控制器激活(三) 前言 在上个篇幅中说到从控制器工厂的GetControllerInstance()方法来执行控制器的注入,本篇要讲是在GetControllerInstanc ...
- 在MVC控制器里面使用dynamic和ExpandoObject,实现数据转义的输出
在很多时候,我们在数据库里面定义表字段和实际在页面中展示的内容,往往是不太匹配的,页面数据可能是多个表数据的综合体,因此除了我们在表设计的时候考虑周到外,还需要考虑数据展现的处理.如果是常规的处理,那 ...
- 学习ASP.NET MVC(二)——我的第一个ASP.NET MVC 控制器
MVC全称是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,是一种软件设计典范,用一种业务逻辑和数据显示分离的方法组织代码,将 ...
- MVC控制器获取@Html.DropDownList值
MVC控制器获取@Html.DropDownList值 发表于 2014 年 4 月 1 日 作者 efour — 暂无评论 先贴一段代码,演示@Html.DropDownList的使用. 前台 前台 ...
- .Net MVC 导入导出Excel总结(三种导出Excel方法,一种导入Excel方法) 通过MVC控制器导出导入Excel文件(可用于java SSH架构)
.Net MVC 导入导出Excel总结(三种导出Excel方法,一种导入Excel方法) [原文地址] 通过MVC控制器导出导入Excel文件(可用于java SSH架构) public cl ...
- 基于MVC4+EasyUI的Web开发框架形成之旅--MVC控制器的设计
自从上篇<基于MVC4+EasyUI的Web开发框架形成之旅--总体介绍>总体性的概括,得到很多同行的关注和支持,不过上一篇主要是介绍一个总体的界面效果和思路,本系列的文章将逐步介绍其中的 ...
随机推荐
- JavaEE(7) - JMS消息事务和异常
1. 使用事务性Session为消息增加事务(NetBeans创建java project: TxSession) MessageSender.java package lee; import jav ...
- http://blog.jobbole.com/50603/#comment-153933
http://blog.jobbole.com/50603/#comment-153933
- Effective C++学习笔记(Part One:Item 1-4)
最近的最终effectvie C++仔细阅读侧,我很惊讶C++动力和魅力.最近的" LL最近记得阅读体验和读书笔记其.必要查找使用,是什么假设总结不合适.欢迎批评: 如今仅仅列出框架,近期会 ...
- ABP领域层——仓储(Repositories)
ABP领域层——仓储(Repositories) 点这里进入ABP系列文章总目录 基于DDD的现代ASP.NET开发框架--ABP系列之11.ABP领域层——仓储(Repositories) ABP是 ...
- 无效 URI: 故障分析证书颁发机构/主机
无效 URI: 分析证书颁发机构/主机 出现该错误的原因是URL中少了一个斜杠.正常的URL是"http:"后边有两个斜杠,而我在改动配置文件里的URL的IP地址部分时.不小心删掉 ...
- MySql创建一个存储过程
MySQL 存储过程是从 MySQL 5.0 新功能.存储过程的长处有一箩筐.只是最基本的还是运行效率和SQL 代码封装. 特别是 SQL 代码封装功能,假设没有存储过程,在外部程序訪问数据库时(比如 ...
- CII-2.4指针常量和常量指针
#define T Stack_T typedef struct T *T; struct T { int count; struct elem { void *x; struct elem *lin ...
- Zepto Code Rush 2014——Dungeons and Candies
题目链接 题意: k个点,每一个点都是一个n * m的char型矩阵.对与每一个点,权值为n * m或者找到一个之前的点,取两个矩阵相应位置不同的字符个数乘以w.找到一个序列,使得全部点的权值和最小 ...
- Redis源代码分析(一)--Redis结构解析
从今天起,本人将会展开对Redis源代码的学习,Redis的代码规模比較小,很适合学习,是一份很不错的学习资料,数了一下大概100个文件左右的样子,用的是C语言写的.希望终于能把他啃完吧,C语言好久不 ...
- 优秀的前端project如何制定一个老师--html学习路径
一个好的前端project教师发展,不是一蹴而就,它需要大量的学习和积累. 至于谁刚开始学习的人,如何入门.学习如何选择我的路线,做了各种工具? 1. 学习之前 1.不要着急看一些复杂网页效果的代码 ...