在上一讲中我们介绍了MvcHandler,知道在Handler里面注入两个接口属性分别为IControllerFactory和IController的factory和controller。并且通过IOC容器ControllerBuilder进行创建对应的ControllerFactory,Mvc默认的ControllerFactory为DefaultControllerFactory;我们可以ControllerBuilder类中通过静态字段Current来修改静态属性_instance中的_SetControllerFactory方法对Func<IControllerFactory> _factoryThunk委托进行赋值,从未不会Mvc运行时不会选择默认的控制器工厂。(有点绕,但说的简单一点可能表达的更为模糊。)

得到了IControllerFactory的实例,我们需要通过IControllerFactory.CreateController(RequestContext requestContext, string controllerName)创建对应的IController实例。这是本节需要讲解的问题。

进入主题(Controller的创建):

Controller的创建以及上一节ControllerFactory的创建的核心思想就是IOC的应用,其最主要的解决的问题就是MVC框架的拓展性问题。(1.我们可以写一个继承IControllerFactory接口的类,意思就是我们可以以我们的思路通过自己写的控制工厂去实现控制器的调用,内存的释放等功能。2.在默认的控制器工厂中,MVC又一次使用同样的思想将控制器的创建权限交给了接口类型为IControllerActivator的属性ControllerActivator。)

由接口函数我们知道,IController实例的创建的权限是交给了IControllerFactory接口类型的实例。在这里我们拿MVC5中默认的控制器工厂(DefaultControllerFactory)进行讲解。在DefaultControllerFactory代码当中,我们发现:

        private IResolver<IControllerActivator> _activatorResolver;
private IControllerActivator _controllerActivator;
 private IControllerActivator ControllerActivator
{
get
{
if (_controllerActivator != null)
{
return _controllerActivator;
}
_controllerActivator = _activatorResolver.Current;
return _controllerActivator;
}
}
protected internal virtual IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
if (controllerType == null)
{
throw new HttpException(,
String.Format(
CultureInfo.CurrentCulture,
MvcResources.DefaultControllerFactory_NoControllerFound,
requestContext.HttpContext.Request.Path));
}
if (!typeof(IController).IsAssignableFrom(controllerType))
{
throw new ArgumentException(
String.Format(
CultureInfo.CurrentCulture,
MvcResources.DefaultControllerFactory_TypeDoesNotSubclassControllerBase,
controllerType),
"controllerType");
}
return ControllerActivator.Create(requestContext, controllerType);
}

控制的创建交给了接口类型为IControllerActivator的字段_controllerActivator,当字段为空的时候通过简单的类型为IResolver<IControllerActivator>的IOC容器对controllerActivator进行赋值。

分析到这里我们发现,我们基本上了解了Controller的创建的整个流程,我们到默认的接口类为IControllerActivator的DefaultControllerActivator中去MVC真正创建Controller的方法。

DefaultControllerActivator创建Controller代码:

            public IController Create(RequestContext requestContext, Type controllerType)
{
try
{
return (IController)(_resolverThunk().GetService(controllerType) ?? Activator.CreateInstance(controllerType));
}
catch (Exception ex)
{
throw new InvalidOperationException(
String.Format(
CultureInfo.CurrentCulture,
MvcResources.DefaultControllerFactory_ErrorCreatingController,
controllerType),
ex);
}
}

未完待续..

MVC5框架解析之Controller的创建的更多相关文章

  1. MVC5框架解析之MvcHandler

    从MvcHandler开始 首选MvcHandler显示实现了IHttpHandler接口中的void ProcessRequest(HttpContext context); 外层逻辑: 1.方法参 ...

  2. Asp.net MVC5 框架揭秘 S412 实例解析 – 绝妙的扩展 模式的胜利

    Asp.net MVC5 框架是个 开源的,处处可扩展的框架. 蒋先生 在他的这本书里 对如何理解框架,如何扩展框架, 给出了大量的说明和实例. 先上效果图 大部分做传统BS 的同学看到这个页面,脑海 ...

  3. ASP.NET MVC5框架揭秘 学习笔记01

    1.自治视图 在早期(作者也没说明是多早,自己猜吧),我们倾向于将所有与UI相关的操作糅合在一起(现在我身边还有很多人这样做),这些操作包括UI界面的呈现. 用户交互操作的捕捉与响应(UI处理逻辑). ...

  4. [转载]iOS 10 UserNotifications 框架解析

    活久见的重构 - iOS 10 UserNotifications 框架解析 TL;DR iOS 10 中以前杂乱的和通知相关的 API 都被统一了,现在开发者可以使用独立的 UserNotifica ...

  5. ABP使用及框架解析系列 - [Unit of Work part.1-概念及使用]

    前言 ABP ABP是“ASP.NET Boilerplate Project”的简称. ABP的官方网站:http://www.aspnetboilerplate.com ABP在Github上的开 ...

  6. ABP使用及框架解析系列 - [Unit of Work part.2-框架实现]

    前言 ABP ABP是“ASP.NET Boilerplate Project”的简称. ABP的官方网站:http://www.aspnetboilerplate.com ABP在Github上的开 ...

  7. iOS 10 UserNotifications 框架解析

    摘自:https://onevcat.com/2016/08/notification/ iOS 10 中以前杂乱的和通知相关的 API 都被统一了,现在开发者可以使用独立的 UserNotifica ...

  8. Poco::TCPServer框架解析

    Poco::TCPServer框架解析 POCO C++ Libraries提供一套 C++ 的类库用以开发基于网络的可移植的应用程序,功能涉及线程.文件.流,网络协议包括:HTTP.FTP.SMTP ...

  9. Sword框架解析——知识采集流程页面初始化

    Sword框架解析——知识采集流程页面初始化 Sword框架解析知识采集流程页面初始化 问题解答流程采集新增页面初始化 1后台t_xt_gnzy表和BLH类 2BLH类的写法前台目录树代码 3登录系统 ...

随机推荐

  1. 【LeetCode】Agorithms 题集(一)

    Single Number 题目 Given an array of integers, every element appears twice except for one. Find that s ...

  2. IFrame 根据嵌入页面自动调节大小

    很多人估计会遇到这样的情况,在IFrame嵌入某些页面,总会出现滚动条,那么有没方法,可以让IFrame随着嵌入页面的内容大小自动调节大小而不出现滚动条呢?答案是肯定的,经过查找,本人发现用Ifram ...

  3. cocos2dx3.1.1+cocosstudio+lua问题总结

    一.DeprecatedEnum.lua no value _G.LAYOUT_ABSOLUTE                 = ccui.Type.ABSOLUTE _G.LAYOUT_LINE ...

  4. mysql导出部分(指定)数据库表字段

      需要导出某个表中的部分字段信息 之前导出数据库表一直使用mysqldump命令,例如: mysqldump -hIP -uroot -P3306 -p 库 表 > 名字.sql 但是如果导出 ...

  5. oracle 查看表属主和表空间sql

    查看表空间 select * from user_tablespaces where table_name = 'TableName' 查看表属主 select  Owner  from all_ta ...

  6. PPPoE Server Under Ubuntu/Debian

    http://imranasghar.blogspot.com/2009/05/pppoe-server-under-ubuntudebian.html ----------------------- ...

  7. java pdu短信解码

    java pdu短信解码 长短信未验证 有兴趣的可以试试 根据python的方法改写的 /** * PDU短信解析 * * * @param pduPayload * @return */ publi ...

  8. hdu1250(Java)大数相加的问题

    Hat's Fibonacci Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Tota ...

  9. tarball文件安装的大概流程

    ./configure这个步骤就是在创建 Makefile 这个文件罗!通常程序开发者会写一支 scripts 来检查你的 Linux 系统.相关的软件属性等等,这个步骤相当的重要, 因为未来你的安装 ...

  10. java与.net平台之间进行RSA加密验证

    RSA加密算法虽然不分平台,标准都是一样的,但是各个平台的实现方式都不尽相同,下面来我来说说java与.net平台之间该如何进行RSA加密验证,即java端加密->.net端验证和.net端加密 ...