ASP.NET MVC 4源代码分析之怎样定位控制器
利用少有的空余时间。具体的浏览了下ASP.NET MVC 4的源代码。照着之前的步伐继续前进(尽管博客园已经存在非常多大牛对MVC源代码分析的博客,可是从个人出发。还是希望自己可以摸索出这些)。
首先有一个事实我们须要明确,就是ASP.NET MVC是基于ASP.NET的,并非独立开来的,所以我们的伊始将会从路由配置入手。
在開始本节之前。须要读者对ASP.NET的路由配置以及C#的扩展方法有一定的掌握,假设读者不理解请依据情况选择以下的文章进行充电:
RouteCollectionExtensions.cs
以下我们打开随意一个ASP.NET MVC项目(以下演示样例均为ASP.NET MVC 4,假设是其它版本号请到响应的文件里查找),打开路由映射的文件(MVC4为App_Start下的RouteConfig.cs文件),能够看到我们再也熟悉只是的配置了。以下我们就来看看MapRoute背后的源代码是什么样的
这种方法是对RouteCollection的扩展。事实上就是RouteTable的Routes。
我们能够看到源代码全然是利用ASP.NET的路由映射创建的,当中的关键点就是这个MvcRouteHandler,这是讲全部符合的请求都经由MVC处理的入口。
MvcRouteHandler.cs
我们顺藤摸瓜来到了MvcRouteHandler。这个类自然也要符合ASP.NET的要求,所以要实现IRouteHandler接口,当中有个关键的方法就是GetHttpHandler,这种方法要求返回一个实现了IHttpHandler接口的类型,而我们能够轻松的看到终于返回了一个MvcHandler类型

MvcHandler.cs
紧接着我们来到MvcHandler这个类,能够看到它不只实现了IHttpHandler接口。同一时候还实现了IHttpAsyncHandler和IRequiresSessionState接口,前者是为了实现异步控制器,后者是为了訪问会话(Session)

然后我们查看接口是怎样实现的
(IHttpHandler中ProcessRequest的实现)

(IHttpAsyncHandler中BeginProcessRequest的实现)

PS:这部分代码比較长,所以没有所有截取。而且重点也不在那。
通过两个截图读者可以看到笔者红色框住的部分,也可以知道他们是我们接下来的主角,从它的參数也可以看出这种方法将会返回给我们控制器的实现(IController)。
以下我们长话短说,直接看这种方法中的关键部分

这里首先通过路由參数获取了控制器的名称,然后调用ControllerBuilder的GetControllerFactory方法获取控制器工厂,我们能够简单的看下GetControllerFactory的是怎样实现的
ControllerBuilder.cs

呵呵,这当然我们要看的。以下我们会看到Current的详细类型

这里笔者就没有继续探索进去了。由于我们已经得出控制器工厂的详细类型是DefaultControllerFactory,那么我们回到MvcHandler中,能够看到在获取了控制器工厂之后。就调用了它的CreateController方法,所以我们就打开DefaultControllerFactory.cs文件一探到底。
DefaultControllerFactory.cs
二话不说。我们直接SearchkeywordCreateController就看到了以下这段代码

OK,我们能够看到在CreateController中首先调用了GetControllerType获取控制器的类型。然后再通过GetControllerInstance将控制器创建出来,既然本文的目的是探索控制器是怎样定位查找的。所以我们就从GetControllerType入手,接招看代码 J

上图只不过默认命名空间的情况。假设读者指定了查找的命名空间则是另外实现的代码,可是当中都是通过调用GetControllerTypeWithinNamespaces来查找的,所以我们就不必在此就留。直接F12来到这种方法中

到了这里,我们不能盲目自信,看到GetControllerTypes就兴冲冲的F12进去,由于在这种方法之前的EnsureInitialized才是真正的关键部分。所以我们要跟进去。
ControllerTypeCache.cs
以下是EnsureInitialized的详细代码

当中我们看到它首先是推断_cache是否为NULL。假设不为NULL是不会进行以下的操作的,这就是为什么第一次訪问页面的时候会非常慢,而之后就非常快了。原因就在这了。当然我们的重点可不是讨论缓存的,我们看到TypeCacheUtil的GetFilteredTypesFromAssemblies返回的了一组类型,而这些就是全部的控制器。所以我们继续追下去。
TypeCacheUtil.cs
下面就是GetFilteredTypesFromAssemblies的代码

我们首先不考虑缓存,觉得当前没有缓存。那么我们就能够发现当中通过调用FilterTypesInAssemblies获取到一组类型。然后才通过SaveTypesToCache保存至缓存中。既然我们先查看FilterTypesInAssemblies的实现代码

到这里我们就快看到湖底了,由于我们看到了Assembly。而这段代码则是通过遍历全部的程序集将全部的类加入进typesSoFar中。然后在return部分通过TypeIsPublicClass过滤一遍,这个时候仅仅会剩下公开的,非纯虚的类了,而predicate则是在ControllerTypeCache中调用GetFilteredTypesFromAssemblies方法时传入的托付。能够见例如以下所看到的的图

而这种方法的详细代码例如以下

呵呵就是推断这个类型是否是Controller结尾,而且是否实现了Icontroller接口,这样我们就获取到了全部的控制器了。
细心的读者会发现FilterTypesInAssemblies方法中buildManager.GetReferencedAssemblies();究竟是调用的什么类型呢?以及什么方法呢?以下我发个图。大家就行明确了

小结
到此为止我们基本上就探索完了,怎样依照路由參数的名称查找到详细的控制器这个任务就留给读者了,由于已经非常明了。本身查找出来的控制器类型就是依照名字、类型保存进字典的,获取就非常easy了。
ASP.NET MVC 4源代码分析之怎样定位控制器的更多相关文章
- ASP.NET MVC源码分析
MVC4 源码分析(Visual studio 2012/2013) HttpModule中重要的UrlRoutingModule 9:this.OnApplicationPostResolveReq ...
- asp.net mvc源码分析-DefaultModelBinder 自定义的普通数据类型的绑定和验证
原文:asp.net mvc源码分析-DefaultModelBinder 自定义的普通数据类型的绑定和验证 在前面的文章中我们曾经涉及到ControllerActionInvoker类GetPara ...
- asp.net mvc源码分析-ModelValidatorProviders 客户端的验证
几年写过asp.net mvc源码分析-ModelValidatorProviders 当时主要是考虑mvc的流程对,客户端的验证也只是简单的提及了一下,现在我们来仔细看一下客户端的验证. 如图所示, ...
- ASP.NET MVC 源码分析(一)
ASP.NET MVC 源码分析(一) 直接上图: 我们先来看Core的设计: 从项目结构来看,asp.net.mvc.core有以下目录: ActionConstraints:action限制相关 ...
- ASP.NET MVC 4源码分析之如何定位控制器
利用少有的空余时间,详细的浏览了下ASP.NET MVC 4的源代码.照着之前的步伐继续前进(虽然博客园已经存在很多大牛对MVC源码分析的博客,但是从个人出发,还是希望自己能够摸索出这些).首先有一个 ...
- Asp.Net MVC 请求原理分析
分析Asp.Net MVC的请求过程,我们从以下几方面看: 配置:IIS网站的配置可以分为两个块:全局 Web.Config 和本站 Web.Config . Asp.Net Routing属于全局性 ...
- ASP.NET MVC 中将数据从View传递到控制器中的三种方法(表单数据绑定)
http://www.cnblogs.com/zyqgold/archive/2010/11/22/1884779.html 在ASP.NET MVC框架中,将视图中的数据传递到控制器中,主要通过发送 ...
- 看透Spring MVC:源代码分析与实践 (Web开发技术丛书)
第一篇 网站基础知识 第1章 网站架构及其演变过程2 1.1 软件的三大类型2 1.2 基础的结构并不简单3 1.3 架构演变的起点5 1.4 海量数据的解决方案5 1.4.1 缓存和页面静态化5 1 ...
- asp.net MVC 源码分析
先上一张图吧 asp.net请求机制的图 by传智播客邹华栋老师 然后是 邹老师添加MVC请求过程的图 其实MVC 是在.netframework上加了一个过滤器 HttpModule 在C:\W ...
随机推荐
- hastable 用法
一,哈希表(Hashtable)简述 在.NET Framework中,Hashtable是System.Collections命名空间提供的一个容器,用于处理和表现类似keyvalue的键值对,其中 ...
- $CF1141A Game 23$
这题很简单啊 可以用\(DFS\)来打 毕竟是 \(2^x*3^y=m 输出x+y啊\) 这是最简单的做法 #include <bits/stdc++.h> using namespace ...
- Mac 的可清除空间(时间机器)
最近项目引入新技术flutter 所以需要更新xcode,下载完了xcode,安装不上 ,费解半天,提示磁盘空间不足.如下图,看到剩余九十多个G, 怎么都解决不了这个问题 就是买磁盘情理软件clean ...
- python爬虫之处理验证码
云打码实现处理验证码 处理验证码,我们需要借助第三方平台来帮我们处理,个人认为云打码处理验证码的准确度还是可以的 首先第一步,我们得先注册一个云打码的账号,普通用户和开发者用户都需要注册一下 然后登陆 ...
- JS——隐式全局变量
在函数中,var声明的是局部变量,不带var的是隐式全局变量 <script> function fn() { var a = b = c = 0;//a是局部变量,b.c是全局变量 va ...
- [Windows Server 2008] 安装IIS7.5及FTP
★ 欢迎来到[护卫神·V课堂],网站地址:http://v.huweishen.com★ 护卫神·V课堂 是护卫神旗下专业提供服务器教学视频的网站,每周更新视频.★ 本节我们将带领大家:安装IISII ...
- 如何设置“用eclipse开发时自动在顶端产生import”?
eclipse新版本中的默认设置可能导致自动在生成import时是在代码中,而大多数时间我们需要自动生成import在代码顶端,按照如下设置即可纠正
- 【转载】HTTP 请求头与请求体
原文地址: https://segmentfault.com/a/1190000006689767 HTTP Request HTTP 的请求报文分为三个部分 请求行.请求头和请求体,格式如图:一个典 ...
- Centos6.6 安装nfs网络文件系统
一.介绍 nfs网络文件系统的,大部分用在内网文件共享,比如,对集群上传文件做共享,经常用在图片部分,当然数据量大了还是要做分离,做为专门的接口比较好,介绍一下基本安装环境: 1)Cnetos6.6 ...
- Redis 之order set有序集合结构及命令详解
1.zadd key score1 value1 score2 value2 添加元素 2.zrem key value1 value2 .. 删除集合中的元素 3.zremrangebyscor ...