即将离职,闲来无事回顾下MVC的源码,到了Controller创建这里,由于流程有点复杂,鉴于自己记性不太好,索性就记录一下吧,方便日后参照。

首先看MvcHandler:

 public class MvcHandler : IHttpAsyncHandler, IHttpHandler, IRequiresSessionState
{
//...
private ControllerBuilder _controllerBuilder;
internal ControllerBuilder ControllerBuilder
{
get
{
if (_controllerBuilder == null)
{
_controllerBuilder = ControllerBuilder.Current;
}
return _controllerBuilder;
}
set { _controllerBuilder = value; }
}
//...
protected internal virtual void ProcessRequest(HttpContextBase httpContext)
{
IController controller;
IControllerFactory factory;
ProcessRequestInit(httpContext, out controller, out factory);

try
{
controller.Execute(RequestContext);
}
finally
{
factory.ReleaseController(controller);
}
} private void ProcessRequestInit(HttpContextBase httpContext, out IController controller, out IControllerFactory factory)
{
// ...
// Get the controller type
string controllerName = RequestContext.RouteData.GetRequiredString("controller"); // Instantiate the controller and call Execute
factory = ControllerBuilder.GetControllerFactory();
controller = factory.CreateController(RequestContext, controllerName);
//...
}
}

简而言之,controller通过实现IControllerFactory的工厂的CreateController()方法创建,而该工厂通过ControllerBuilder.GetControllerFactory()获得,而ControllerBuilder通过ControllerBuilder类型的一个静态属性Current获得,显然Current是ControllerBuilder类型的一个单例。

那么来看看ControllerBuidler:

public class ControllerBuilder
{
private static ControllerBuilder _instance = new ControllerBuilder();
private Func<IControllerFactory> _factoryThunk = () => null;
private HashSet<string> _namespaces = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
private IResolver<IControllerFactory> _serviceResolver;
public ControllerBuilder()
: this(null)
{
} internal ControllerBuilder(IResolver<IControllerFactory> serviceResolver)
{
_serviceResolver = serviceResolver ?? new SingleServiceResolver<IControllerFactory>(
() => _factoryThunk(),
new DefaultControllerFactory { ControllerBuilder = this },
"ControllerBuilder.GetControllerFactory"
);
} public static ControllerBuilder Current
{
get { return _instance; }
}
public IControllerFactory GetControllerFactory()
{
return _serviceResolver.Current;
} public void SetControllerFactory(IControllerFactory controllerFactory)
{
if (controllerFactory == null)
{
throw new ArgumentNullException("controllerFactory");
} _factoryThunk = () => controllerFactory;
}
//...
}
GetControllerFactory()方法返回一个IResolver<IControllerFactory>类型实例的Current属性,默认为SingleServiceResolver<IControllerFactory>类型。

以下是SingleServiceResolver<IControllerFactory>的部分实现:

internal class SingleServiceResolver<TService> : IResolver<TService>
where TService : class
{
private Lazy<TService> _currentValueFromResolver;
private Func<TService> _currentValueThunk;
private TService _defaultValue;
private Func<IDependencyResolver> _resolverThunk;
private string _callerMethodName; public SingleServiceResolver(Func<TService> currentValueThunk, TService defaultValue, string callerMethodName)
{
_resolverThunk = () => DependencyResolver.Current;
_currentValueFromResolver = new Lazy<TService>(GetValueFromResolver);
_currentValueThunk = currentValueThunk;
_defaultValue =
defaultValue;
_callerMethodName = callerMethodName;
} internal SingleServiceResolver(Func<TService> staticAccessor, TService defaultValue, IDependencyResolver resolver, string callerMethodName)
: this(staticAccessor, defaultValue, callerMethodName)
{
if (resolver != null)
{
_resolverThunk = () => resolver;
}
} public TService Current
{
get { return _currentValueFromResolver.Value ?? _currentValueThunk() ?? _defaultValue; }
} private TService GetValueFromResolver()
{
TService result = _resolverThunk().GetService<TService>(); if (result != null && _currentValueThunk() != null)
{
return result;
}
}

由此可见Current属性返回的值有一个优先级:

优先级最低的是_defaultValue,_defaultValue在构造函数中通过参数传递进来,在之前的CotrollerBuilder中可以看到,这个默认值是一个DefaultFactory类型实例;

次优先级的是对_currentValueThunk委托的调用,也在构造函数中作为参数传递进来,默认返回Null,并且可以通过CotrollerBuilder的SetControllerFactory()方法进行设置;

最高优先级的是一个GetValueFromResolver()方法的返回值,并通过Lazy<>实现延迟执行,GetValueFromResolver()方法内部,首先是对_resolverThunk委托的调用,该委托可通过构造函数的参数传递,否则返回一个DependencyResolver的Current属性,DependencyResolver我们就比较熟悉了,它用于IOC容器的设置和构建,关于它篇幅所限在后面详解吧,该属性返回一个IDependencyResolver类型实例,默认为MVC内部的一个IOC容器DefaultDependencyResolver,由于默认TService类型是一个接口类型,所以DefaultDependencyResolver的GetService()方法默认返回Null。

ControllerFactory的整个创建过程就是这样了。

MVC5 Controller简要创建过程(1):ControllerFactory的创建的更多相关文章

  1. MVC5 Controller简要创建过程(2):由ControllerFactory创建Controller

    上文已经完成了ControllerFactory的创建,接下来就是调用其CreateController()方法创建Controller了. DefaultControllerFactory中Crea ...

  2. Spring MVC 原理探秘 - 容器的创建过程

    1.简介 在上一篇文章中,我向大家介绍了 Spring MVC 是如何处理 HTTP 请求的.Spring MVC 可对外提供服务时,说明其已经处于了就绪状态.再次之前,Spring MVC 需要进行 ...

  3. windows进程/线程创建过程 --- windows操作系统学习

    有了之前的对进程和线程对象的学习的铺垫后,我们现在可以开始学习windows下的进程创建过程了,我将尝试着从源代码的层次来分析在windows下创建一个进程都要涉及到哪些步骤,都要涉及到哪些数据结构. ...

  4. 0003 - 基于xml的Spring Bean 的创建过程

    一.目录 前言 创建 Bean 容器 加载 Bean 定义 创建 Bean Spring Bean 创建过程中的设计模式 总结 二.前言 2.1 Spring 使用配置 ApplicationCont ...

  5. Android深入理解Context(二)Activity和Service的Context创建过程

    前言 上一篇文章我们学习了Context关联类和Application Context的创建过程,这一篇我们接着来学习Activity和Service的Context创建过程.需要注意的是,本篇的知识 ...

  6. Spring源码解析 – AnnotationConfigApplicationContext容器创建过程

    Spring在BeanFactory基础上提供了一些列具体容器的实现,其中AnnotationConfigApplicationContext是一个用来管理注解bean的容器,从AnnotationC ...

  7. Python之变量的创建过程

    Python之变量的创建过程 一.变量创建过程 首先,当我们定义了一个变量name = 'Kwan'的时候,在内存中其实是做了这样一件事: 程序开辟了一块内存空间,将'Kwan'存储进去,再让变量名n ...

  8. Java对象的创建过程:类的初始化与实例化

    一.Java对象创建时机 我们知道,一个对象在可以被使用之前必须要被正确地实例化.在Java代码中,有很多行为可以引起对象的创建,最为直观的一种就是使用new关键字来调用一个类的构造函数显式地创建对象 ...

  9. .NET/ASP.NET MVC Controller 控制器(IController控制器的创建过程)

    阅读目录: 1.开篇介绍 2.ASP.NETMVC IControllerFactory 控制器工厂接口 3.ASP.NETMVC DefaultControllerFactory 默认控制器工厂 4 ...

随机推荐

  1. C语言运算符的优先级

    熟悉C语言的同学都知道,C语言众多的运算符及繁琐难记的优先级总是搞得我们这些C初学者头大.那么本文就 对C语言中所有的运算符进行汇总,并对其优先级进行一定的介绍. 这里虽然对所有C运算符的优先级进行了 ...

  2. OpenStack ceilometer部署安装监控,计费数据抓取测试Ok

  3. 泛泰A900 刷4.4专用中文TWRP2.7.1.1版 支持自己主动识别手机版本号(全球首创)

    因本人手上的A900S已砖, 所以临时弄不了ROM了, 先上传之前已经弄好的刷4.4专用的新版TWRP recovery 2.7.1.1  这个版本号是我自己定义的,为差别之前公布的2.7.0.0版( ...

  4. 求S=a+aa+aaa+aaaa+aa...a的值

    问题描述:求S=a+aa+aaa+aaaa+aa...a的值,其中a是一个数字,由输入a(1 <= a <= 9)表示,相加的元素个数由输入b(b<= 1000)表示. 这个算法的优 ...

  5. ProgressBar、RatingBar和Spinner控件

    1.ProgressBar.SeekBar与RatingBar控件 ProgressBar控件,也就是我们通常的进度条控件,可以显示加载的进度等.SeekBar控件,滑块控件,可以根据用户的需要动态为 ...

  6. Android布局(一)layout_gravity 属性和 gravity属性的区别

    安卓中的 layout_gravity 属性和 gravity属性 有啥区别? LinearLayout有两个非常相似的属性: android:gravity与android:layout_gravi ...

  7. 对 PInvoke 函数“WinVideo!WinVideo.webcam::SendMessage”的调用导致堆栈不对称

    从.NET1.1升级到.NET2.0时出现的PInvokeStackImbalance错误微软官方的解释 (http://msdn2.microsoft.com/zh-cn/library/0htdy ...

  8. 记一次dedeCMS网站搭建全过程

    Step 1 使用阿里云Windows Server 2012服务器 { 使用远程桌面进行操作,ip admin pwd登录 } Step 2 下载安装phpStudy包 { 下载安装,直接安装到C盘 ...

  9. VC com 通信实例

    HANDLE hCom;//全局變量串口句柄 COMMTIMEOUTS TimeOuts; DCB dcb; 按鈕代碼() { hCom=CreateFile(L“COM1”,// 串口名稱 GENE ...

  10. 设计模式之适配器模式(Decorator)

    1.意图 动态地给一个对象添加一些额外的功能. 2.适用性 动态.透明的方式给单个对象添加职责. 如果不适合适用子类来进行扩展的时候,可以考虑适用装饰模式. 避免子类数目爆炸性增长. 3.结构 4.参 ...