深入理解ASP.NET MVC(5)
回顾
系列的前4节深入剖析了ASP.NET URL路由机制,以及MVC在此基础上是如何实现Areas机制的,同时涉及到inbound和outbound很多细节部分。第2节中提到MvcRouteHandler是MVC框架的入口,这节开始,从MvcRouteHandler往下说开去。
Controller的创建过程:Builder和Factory
MvcRouteHandler的实现仅仅是通过GetHttpHandler方法返回一个MvcHandler实例,MvcHandler从RouteData中获得controller名字负责创建一个ControllerBuilder的实例,并通过ControllerBuilder的GetControllerFactory返回一个IControllerFactory的实例,这个实例就是DefaultControllerFactory,它的 CreateController方法负责创建需要的Controller实例。下面这段代码来自MvcHandler:
1
2
3
4
5
|
// Get the controller type string controllerName = RequestContext.RouteData.GetRequiredString( "controller" ); // Instantiate the controller and call Execute factory = ControllerBuilder.GetControllerFactory(); controller = factory.CreateController(RequestContext, controllerName); |
DefaultControllerFactory创建Controller分两步:
1
2
|
Type controllerType = GetControllerType(requestContext, controllerName); IController controller = GetControllerInstance(requestContext, controllerType); |
GetControllerInstance最终是这样创建controller的:
1
|
return (IController)Activator.CreateInstance(controllerType); |
这就使得要使用DI设计模式十分困难。好在我们可以重写GetControllerInstance,并应用各种DI。受书中的影响,个人使用的是Ninject。
另外,为了加快GetControllerType方法,DefaultControllerFactory内部运用缓存机制将当前程序和所有引用程序集的类型缓存成哈希表。
还可以通过如下方法,提供某些名字空间较高的优先级来优化搜索。
1
2
3
4
5
6
|
protected void Application_Start() { RegisterRoutes(RouteTable.Routes); ControllerBuilder.Current.DefaultNamespaces.Add( "MyApp.Controllers.*" ); ControllerBuilder.Current.DefaultNamespaces.Add( "OtherAssembly.MyNamespace.*" ); } |
上面这种设置名字空间的优先级仍然低于在设置路由表时为某个路由指定的名字空间,Areas机制就是靠在设置路由表时指定名字空间实现的,详见深入理解ASP.NET MVC(4)。
也可以在ControllerBuilder层面上替换ControllerFactory:
1
2
3
4
5
|
protected void Application_Start() { RegisterRoutes(RouteTable.Routes); ControllerBuilder.Current.SetControllerFactory( new MyControllerFactory()); } |
Controller的调用:Controller只是普通的.NET类
MvcHandler依靠ControllerBuilder和IControllerFactory获得Controller的实例后,调用Controller实例的Execute方法,在该方法返回后再调用IControllerFactory的ReleaseController收尾。由此看出Controller的Execute做了所有的事情,看似“功能强大”,其实它只是.NET的普通类, MVC框架赋予其“非凡”的能力:
所有的Controller只要实现一个接口,IController,接口的定义了Execute方法:
1
2
3
4
5
6
7
|
namespace System.Web.Mvc { using System.Web.Routing; public interface IController { void Execute(RequestContext requestContext); } } |
从接口定义可以看出,当Controller被“调用”的时候,应该负责完成Execute方法,参数RequestContext封装了HttpContext,所以可以像下面这样直接实现一个Controller,同样可以工作:
1
2
3
4
5
6
7
|
public class HelloWorldController : IController { public void Execute(RequestContext requestContext) { requestContext.HttpContext.Response.Write( "Hello, world!" ); } } |
然而,需要的逻辑和架构远比这个复杂的多,因此MVC框架提供了如下类关系:
IController->ControllerBase->Controller
其中ControllerBase实现Execute,Execute在内部调用ExecuteCore,ExecuteCore作为一个抽象方 法,延迟到Controller中实现。ControllerBase只提供了诸如TempData、ViewData等,Controller的 ExecuteCore方法真正invoke了action机制,是action的入口。下面的代码是ExecuteCore的实现:
1
2
3
4
5
6
7
8
9
10
|
PossiblyLoadTempData(); try { string actionName = RouteData.GetRequiredString( "action" ); if (!ActionInvoker.InvokeAction(ControllerContext, actionName)) { HandleUnknownAction(actionName); } } finally { PossiblySaveTempData(); } |
可以看到RouteData在这里又提供了action参数,可以想象InvokeAction方法依靠这个action的名字调用action,并实现诸多验证机制。下节开始讨论action逻辑。
劳动果实,转载请注明出处:http://www.cnblogs.com/P_Chou/archive/2010/11/20/details-asp-net-mvc-05.html
深入理解ASP.NET MVC(5)的更多相关文章
- 七天学会ASP.NET MVC (一)——深入理解ASP.NET MVC
系列文章 七天学会ASP.NET MVC (一)——深入理解ASP.NET MVC 七天学会ASP.NET MVC (二)——ASP.NET MVC 数据传递 七天学会ASP.NET MVC (三)— ...
- [转载]深入理解ASP.NET MVC之ActionResult
Action全局观 在上一篇最后,我们进行到了Action调用的“门口”: 1 if (!ActionInvoker.InvokeAction(ControllerContext, actionNam ...
- 深入理解ASP.NET MVC Day1
深入理解ASP.NET MVC ASP.NET vs MVC vs WebForms 许多ASP.NET开发人员开始接触MVC认为MVC与ASP.NET完全没有关系,是一个全新的Web开发,事实上 ...
- 七天学会ASP.NET MVC ——深入理解ASP.NET MVC
七天学会ASP.NET MVC (一)——深入理解ASP.NET MVC 系列文章 七天学会ASP.NET MVC (一)——深入理解ASP.NET MVC 七天学会ASP.NET MVC (二) ...
- 深入理解ASP.NET MVC(6)
系列目录 Action全局观 在上一篇最后,我们进行到了Action调用的“门口”: 1 if (!ActionInvoker.InvokeAction(ControllerContext, acti ...
- 深入理解ASP.NET MVC(目录)
学ASP.NET MVC2有一段时间了,也针对性的做了个练习.感觉这个框架还是不错的,所以决定要深入系统的学习一下.看到这样一本书: 作者博客:http://blog.stevensanderson. ...
- 七天学会ASP.NET MVC (一)——深入理解ASP.NET MVC 【转】
http://www.cnblogs.com/powertoolsteam/p/MVC_one.html 系列文章 七天学会ASP.NET MVC (一)——深入理解ASP.NET MVC 七天学会A ...
- [转载] ASP.NET MVC (一)——深入理解ASP.NET MVC
个人认为写得比较透彻得Asp.net mvc 文章,所以转载过来,原文链接在最后: ASP.NET vs MVC vs WebForms 许多ASP.NET开发人员开始接触MVC认为MVC与ASP.N ...
- 理解ASP.NET MVC的路由系统
引言 路由,正如其名,是决定消息经由何处被传递到何处的过程.也正如网络设备路由器Router一样,ASP.NET MVC框架处理请求URL的方式,同样依赖于一张预定义的路由表.以该路由表为转发依据,请 ...
随机推荐
- mail命令入门及进阶
mail是linux shell中的邮件工具,与crontab配合使用,可以实现定期发送邮件.本文主要介绍mail工具使用方法及注意事项. 1.mail命令一般用法: mail –s "邮件 ...
- Js代码一些要素
---恢复内容开始--- 条件语句 is(条件){ 语句 }else { 语句 } {}在js中我们把他叫代码块.如果代码块里内容没有执行完,语句就不会向下执行. 代码块是一个独立的整体.如果js中莫 ...
- python day16--面向对象(01)
一.概念 类:具有相同属性的一类事物 比如人类是类,人类中的某个人是对象.食物是一类,米饭是一个对象 class Person: '''类体:两部分:变量部分,方法(函数)部分''' mind = ' ...
- 位图(bitmap)—— C语言实现
高级数据结构及应用 -- 使用 bitmap 进行字符串去重 位图应当具备的置一,清零,以及判断三大功能: #define BITS_PER_WORD 32 #define MASK 0x1f #de ...
- Android Native Hook技术(二)
Hook技术应用 已经介绍了安卓 Native hook 原理,这里介绍 hook 技术的应用,及 Cyida Substrate 框架. 分析某APP,发现其POST请求数据经过加密,我们希望还原其 ...
- 【计算机视觉】seetaFace
class impl class FaceDetection::Impl { public: Impl() : detector_(new seeta::fd::FuStDetector()), sl ...
- NodeServices
NodeServices https://www.cnblogs.com/stulzq/p/10535310.html 一.前言 在 .NET Framework 时,我们可以通过V8.NET等组件来 ...
- Python的文件处理
引子 1.问题:给你一个文件 "兼职白领学生空姐模特护士联系方式.txt" ,如何查看内容? 答: 安装文本编辑器软件 选中右键,利用文本编辑器软件打开 查看 or 写入 保存,关 ...
- Spring——使用自定义标签
文章内容参考了<Spring源码深度解析>一书.自己照着书中内容做了一遍,不懂的地方以及采坑的地方会在文中记录. 推荐一篇post,关于Spring配置文件的命名空间: https://w ...
- 堆栈详解 + 彻底理解Java的值传递和引用传递
本文旨在用最通俗的语言讲述最枯燥的基本知识 学过Java基础的人都知道:值传递和引用传递是初次接触Java时的一个难点,有时候记得了语法却记不得怎么实际运用,有时候会的了运用却解释不出原理,而且坊间讨 ...