发现只要涉及到对象的创建,都很喜欢用工厂模式来解决耦合性的问题,微软从最初的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() { |
_serviceResolver的定义如下:
private IResolver<IControllerFactory> _serviceResolver; |
Current属性定义在泛型接口IResolver<T>中,具体代码如下:
internal interface IResolver<T> { |
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对象。