mvc源码解读(5)Controller工厂的创建

      发现只要涉及到对象的创建,都很喜欢用工厂模式来解决耦合性的问题,微软从最初的PetShop4中就大量的使用了工厂模式+反射的技术解决模块之间的耦合性问题,屡试不爽。无论是WebForm模式下还是mvc模式下,我们随处可见到各种各样的工厂模式创建对象。但是在一篇文章呢,我们来讲mvc中这个用来创建各种各样对象的工厂是如何创建的。

      我们首先回到之前我们讲到的那个MvcHandler类,里面有一个出处理请求初始化的方法ProcessRequestInit,我们来看看这个方法里面主要涉及到获取Controller工厂的代码:

 private void ProcessRequestInit(HttpContextBase httpContext, out IController controller, out IControllerFactory factory)

{

       ..................................................................

       factory = ControllerBuilder.GetControllerFactory();

       ..................................................................

}

不多说,我们直接看看ControllerBuilder中GetControllerFactory()方法的实现:

public IControllerFactory GetControllerFactory()

{
            return _serviceResolver.Current;
 }

_serviceResolver的定义如下:

private IResolver<IControllerFactory> _serviceResolver;

Current属性定义在泛型接口IResolver<T>中,具体代码如下:

internal interface IResolver<T>

{
        T Current { get; }
 }

 mvc中默认的Controller工厂DefaultControllerFactory实现了该接口,因此从以上代码分析可知上文中的factory实际上就是DefaultControllerFactory类的实例。当然以上只是系统默认给我们定义的控制器工厂,如果我们要创建自己的控制器工厂呢?我们在ControllerBuilder类里面可以发现两个设置控制器工厂的重载方法:方法一:

 public void SetControllerFactory(IControllerFactory controllerFactory)

{            

       if (controllerFactory == null)

         {                

                  throw new ArgumentNullException("controllerFactory");            

         }

              _factoryThunk = () => controllerFactory;        

}

我们用第一种重载方法的话,需要在全局文件Application_Start()方法中注册我们的工厂:具体代码如下:

            ControllerBuilder.Current.SetControllerFactory(XXXX);

其中XXX代表了一个实现了IControllerFactory接口的对象实例,如果要看具体的示例,我觉得博客园上排名第一的蒋金楠老师的这一篇文章写的太好了,我们只是一直在模仿,从未被超越:http://www.cnblogs.com/artech/archive/2012/03/31/controller-activation-02.html

方法二:

public void SetControllerFactory(Type controllerFactoryType)

{      

...................................................................................      

      _factoryThunk = delegate() { 

          try {                    

                    return (IControllerFactory)Activator.CreateInstance(controllerFactoryType);                

               } catch (Exception ex) {     

....................................................................................                       

            };        

}

 这个方法是配合是配合使用Web.Config配置文件来使用的,这里不做详解,大家只要知道第一种创建Controller的工厂就ok了~~~

 通过对源码的分析我们可以知道假如我们没有手动的调用SetControllerFactory这两个重载的方法,系统就会默认的调用DefaultControllerFactory这个默认的工厂来创建我们的Controller对象。

原文地址:https://www.cnblogs.com/ghhlyy/p/2887352.html