ASP.NET没有魔法——ASP.NET MVC Controller的实例化与执行
上一章节中对路由的注册和匹配过程进行了介绍,知道了MVC的Http请求最终是交由MvcHandler处理的,而其处理过程就是对Controller的创建、执行和释放。
本章将从以下几点进一步对上面提到的三个过程进行介绍:
● MvcHandler概述
● ControllerBuilder&ControllerFactory
● DefaultControllerFactory
● Controller&ControllerBase
● Controller的执行
MvcHandler概述
MvcHandler是MVC的核心组件,用于接收并处理来自客户的MVC请求,以下是MvcHandler类型的定义:

MvcHandler实现了IHttpHandler和异步的IHttpAsyncHandler接口,这两个接口是用于处理Http请求的接口,其实这里所谓的“处理”就是根据用户请求的信息来生成一个响应信息返回到客户端。所以Mvc中也一样,通过Http请求的Head、Body等信息从中抓取需要的数据,然后将其传入Controller的Action中执行业务逻辑后,渲染一个Html模板返回至客户端显示。
它的构造需要一个RequestContext对象。而RequestContext其实是HttpContextBase(包含了HTTP请求的所有信息)和RouteData的封装,这个对象是在UrlRoutingModule中创建的,然后通过MvcRouteHandler传到了MvcHandler中。
以下是MvcHandler的处理概况图:


ControllerBuilder&ControllerFactory
MvcHandler执行的一个步骤就是初始化,其中最重要的就是创建Controller,而Controller的创建离不开ControllerBuilder和ControllerFactory,那么它们到底起到什么作用?
1. ControllerBuilder:用于获取和设置ControllerFactory,在没有设置过ControllerFactory的情况下默认获得DefaultControllerFactory。
以下是ControllerBuilder的定义:

2. ControllerFactory:它其实是一个IControllerFactory接口,专门用于创建和销毁Controller。MVC的默认实现是DefaultControllerFactory。

综上所述,ControllerBuilder用于创建ControllerFactory,而ControllerFactory用于创建Controller,而ControllerFactory的默认实现是DefaultControllerFactory。
DefaultControllerFactory
以下是DefaultControllerFactory的定义:

它除了实现IControllerFactory的方法外还有两个名为GetControllerInstance、GetControllerType的受保护的虚方法,另外构造方法有一个类型为IControllerActivator的参数。前者很容易理解,在.Net中可以通过一个类型来创建一个实例,而可以通过类型名称在程序集中找到对应的类型。所以可以想到的是两个方法分别就是根据Controller的名称获取类型然后在通过类型创建实例的方法。而后者从名称看来是Controller的激活器,那它的作用是什么呢?是用来创建Controller实例的吗?
以下是CreateController的代码,从代码中也证实了上面的猜测,Controller的创建是先根据Controller名称查找类型,然后通过类型创建Controller实例。

1. Controller类型的查找:
1). 命名空间的处理:路由中的命名空间、ControllerBuilder中的命名空间、无命名空间;三种命名空间从前到后依次以其值来作为命名空间匹配,直到找到对应Controller的类型。换句话说如果路由对象和Controller Builder都设置了命名空间,那么先根据路由对象的去查找,如果找不到再使用ControllerBuilder设置的命名空间,如果仍然没有就不使用命名空间来进行匹配。
2). Controller类型缓存数据处理:为了提高MVC的性能,在通过缓存的形式在第一次查找Controller类型的时候遍历所有依赖程序集中的IController类型生成一个名称为“MVC-ControllerTypeCache.xml”缓存文件(由ControllerTypeCache类型完成),以下是缓存文件格式:

注:该缓存路径一般在systemroot\Microsoft .NET\Framework\versionNumber\Temporary ASP.NET Files\{app name}\..\..\UserCache或systemroot\Microsoft .NET\Framework\versionNumber\Temporary ASP.NET Files\root\..\..\UserCache目录下,但是可能由于Web宿主不同或环境配置不同而不同,但是可以在代码中通过HttpRuntime.CodegenDir属性找到。另外还有一个缓存文件是对Area注册的缓存,名称为MVC-AreaRegistrationTypeCache.xml。
3). 类型的匹配:Controller的类型匹配相对简单,它使用{NameSpace}.{ControllerName}的形式在上面文件的数据结构中匹配。
2. Controller的创建:
1). 判断Controller类型是否是继承于IController。
2). 通过ControllerActivator创建Controller实例。
3. 关于ControllerActivator:用于Controller的创建,在MVC中有一个DefaultControllerActivator存在于DefaultControllerFactory中,它用于通过.Net中的Activator对象或依赖解析器创建Controller实例。

Controller&ControllerBase
在开发中MVC控制器的时候,一般以Controller类型作为基类,通过继承的方式来完成。这样可以轻松的获得Controller基类提供的功能。而Controller其实是继承至ControllerBase抽象类,ControllerBase中提供了MVC中最核心的Execute方法和ExecuteCore抽象方法以及必要的一些属性如TempDataDictionary以及ViewDataDictionary等,使用典型的模板模式规定了Controller类型的框架。
1. ControllerBase:定义了Controller的核心框架

2. Controller:实现了ASP.NET MVC中控制器的执行逻辑,以及附加功能,如验证、异常处理、事件处理(Action执行事件、验证事件等)、跳转、多种返回类型(包括但不限于MVC页面、Json数据、文件、普通内容)等。
注:由于Controller定义代码太多,所以不在放出,大家可以在VS中查看。
Controller的执行
上面提到过ControllerBase是整个Controller类结构的模板,所以在ASP.NET MVC调用Controller执行时实际上是调用的ControllerBase类型的Execute方法,而该方法内部实际上调用的是子类的ExecuteCore方法,以下是Controller类型的ExecuteCore:

从代码可以看出Controller的执行“很”简单,只有四步:加载临时数据、获取Action、执行Action、保存临时数据。
注:本章不再对Action的执行进行介绍,因为Action的执行包含了很多内容,比如过滤器的执行、模型的绑定等,所以这些内容会在后续讲解。
小结
本章以MvcHandler的执行为入口,以MVC控制器的创建、执行为流程,介绍了其相关的重要对象和执行逻辑。更多内容请关注后续文章。
本文链接:http://www.cnblogs.com/selimsong/p/7677108.html
ASP.NET没有魔法——ASP.NET MVC Controller的实例化与执行的更多相关文章
- ASP.NET没有魔法——ASP.NET MVC 过滤器(Filter)
上一篇文章介绍了使用Authorize特性实现了ASP.NET MVC中针对Controller或者Action的授权功能,实际上这个特性是MVC功能的一部分,被称为过滤器(Filter),它是一种面 ...
- ASP.NET没有魔法——ASP.NET MVC 模型绑定解析(下篇)
上一篇<ASP.NET没有魔法——ASP.NET MVC 模型绑定解析(上篇)>文章介绍了ASP.NET MVC模型绑定的相关组件和概念,本章将介绍Controller在执行时是如何通过这 ...
- ASP.NET没有魔法——ASP.NET MVC 路由的匹配与处理
ASP.NET MVC的路由是MVC应用的一个核心也是MVC应用处理的入口,作为一个开发者,在正常情况下仅仅需要做的就是根据需求去定义实体.业务逻辑,然后在MVC的Controller中去调用.Vie ...
- ASP.NET没有魔法——ASP.NET MVC IoC
之前的文章介绍了MVC如何通过ControllerFactory及ControllerActivator创建Controller,而Controller又是如何通过ControllerBase这个模板 ...
- ASP.NET没有魔法——ASP.NET MVC使用Oauth2.0实现身份验证
随着软件的不断发展,出现了更多的身份验证使用场景,除了典型的服务器与客户端之间的身份验证外还有,如服务与服务之间的(如微服务架构).服务器与多种客户端的(如PC.移动.Web等),甚至还有需要以服务的 ...
- ASP.NET没有魔法——ASP.NET MVC Razor与View渲染
对于Web应用来说,它的界面是由浏览器根据HTML代码及其引用的相关资源进行渲染后展示给用户的结果,换句话说Web应用的界面呈现工作是由浏览器完成的,Web应用的原理是通过Http协议从服务器上获取到 ...
- ASP.NET没有魔法——ASP.NET MVC Razor与View渲染 ASP.NET没有魔法——ASP.NET MVC界面美化及使用Bundle完成静态资源管理
ASP.NET没有魔法——ASP.NET MVC Razor与View渲染 对于Web应用来说,它的界面是由浏览器根据HTML代码及其引用的相关资源进行渲染后展示给用户的结果,换句话说Web应用的 ...
- ASP.NET没有魔法——ASP.NET MVC 与数据库大集合
ASP.NET没有魔法——ASP.NET与数据库 ASP.NET没有魔法——ASP.NET MVC 与数据库之MySQL ASP.NET没有魔法——ASP.NET MVC 与数据库之ORM ASP.N ...
- ASP.NET没有魔法——ASP.NET 身份验证与Identity
前面的文章中为My Blog加入了文章的管理功能(ASP.NET没有魔法——ASP.NET MVC使用Area开发一个管理模块),但是管理功能应该只能由“作者”来访问,那么要如何控制用户的访问权限?也 ...
随机推荐
- JS表单提交的几种方式
第一种方式 : 表单提交,在 form 标签中增加 onsubmit 事件来判断表单是否提交成功 <script type="text/javascript"> fun ...
- webpack2使用ch4-向根目录index.html文件传参并使用参数 使用线上资源 压缩html
1 webpack.config.js const webpack = require('webpack'), htmlWebpackPlugin = require('html-webpack-pl ...
- PE格式第四讲,数据目录表之导入表,以及IAT表
PE格式第四讲,数据目录表之导入表,以及IAT表 一丶IAT(地址表) 首先我们思考一个问题,程序加载的时候会调用API,比如我们以前写的标准PE 那么他到底是怎么去调用的? 他会Call 下边的Jm ...
- sqlserver 2005连接超时采用bat命令解决
将以下内容保存为 openSql.bat 双击运行即可 @echo ========= SQL Server Ports =================== @echo Enabling SQLS ...
- ICommand.CanExecuteChanged事件订阅对象的变化
public class DelegateCommand : ICommand { Func<object, bool> canExecute; Action<object> ...
- 阿里巴巴Java规约插件试用
阿里Java开发规约Eclipse插件介绍 阿里巴巴集团配合<阿里巴巴Java开发手册>PDF终极版开发的IDE插件,目前包括IDEA插件.Eclipse插件. 安装 检查环境 插件要求: ...
- Python和SQL 2017的强大功能
Python和SQL Server 2017的强大功能 原文来自:https://www.red-gate.com/simple-talk/sql/sql-development/power-py ...
- Gradle sync failed 异常
今天开发过程中出现如下异常 Gradle sync failed: Connection timed out: connect. If you are behind an HTTP proxy, pl ...
- checkbox插件
1.全选或者全不选 首先判断全选或全不选checkbox是否被选中. 如果被选中,则为每个选项checkbox设置obj.checked='checked'; 如果未被选中,则为每个选项checkbo ...
- 系统讲解CSS,前端开发最神奇的技术,新手的你一定不能错过
前面小编带领大家重温了前端开发中最基本的HTML语言.如果你已经掌握了这门语言,那么恭喜你,可以去深入了解CSS技术了.CSS技术最主要的功能就是弥补HTML标记对在页面中显示外观的不足,对这些标记对 ...