ASP.NET MVC Controller激活系统详解:IoC的应用[下篇]2012-11-16 博客园 Artech[上篇]除了通过自定义ControllerFactory的方式引入IoC之外,在使用默认DefaultControllerFactory情况下也可以通过一些扩展使基于IoC的Controller激活成为可能。主要的方式就是自定义ControllerActivator和 DependencyResolver。四、ControllerActivator V.S. DependencyResolver如下面的代码片断所示,DefaultControllerFactory具有两个构造函数重载,其中一个具有一个类型为IControllerActivator接口的参数,我们将实现了该接口得类型统称为ControllerActivator。
 1: public class DefaultControllerFactory : IControllerFactory
 2: {
 3: //其他成员
 4: public DefaultControllerFactory();
 5: public DefaultControllerFactory(IControllerActivator controllerActivator);
 6: }
顾名思义,ControllerActivator就是Controller的“激活器”,Controller的激活实现在唯一的Create方法中。如下面的代码所示,该方法具有两个参数(requestContext和controllerType),分别代表当前请求上下文和解析出来的目标Controller的类型。
 1: public interface IControllerActivator
 2: {
 3: IController Create(RequestContext requestContext, Type controllerType);
 4: }
在默认的情况下(调用DefaultControllerFactory默认构造函数或者指定的参数为Null),Controller激活系统 会默认使用一个类型为DefaultControllerActivator的对象。如下面的代码片断所示,DefaultControllerActivator是一个实现了IControllerActivator私有类型而已,我们不能直接通过编程的方式使用它。
 1: private class DefaultControllerActivator : IControllerActivator
 2: {
 3: public DefaultControllerActivator();
 4: public DefaultControllerActivator(IDependencyResolver resolver);
 5:public IController Create(RequestContext requestContext,Type controllerType);
 6: }
DefaultControllerActivator的构造函数具有一个类型为IDependencyResolver的参数,这是一个重要的接口,我们将实现了该接口的类型统称为DependencyResolver。。如下面的代码片断所示,IDependencyResolver接口具有两个方法GetService和GetServices,用于根据指定的类型获取单个或者多个实例。实际上DefaultControllerActivator就是通过调用GetService方法获取具体的Controller对象的
 1: public interface IDependencyResolver
 2: {
 3: object GetService(Type serviceType);
 4: IEnumerable<object> GetServices(Type serviceType);
 5: }
如果在构造DefaultControllerActivator对象的时候传入的参数为Null,那么Controller激活系统会使用通过DependencyResolver的静态只读属性Current表示DependencyResolver。需要提醒的是,DependencyResolver类型没有实现IDependencyResolver接口,而是对一个实现了IDependencyResolver接口类型对象的封装。
 1: public class DependencyResolver
 2: {
 3: private static DependencyResolver _instance;
 4:
 5: public void InnerSetResolver(object commonServiceLocator);
 6: public void InnerSetResolver(IDependencyResolver resolver);
 7: public void InnerSetResolver(Func<Type, object> getService, Func<Type, IEnumerable<object>> getServices);
 8:
 9: public static void SetResolver(object commonServiceLocator);
10: public static void SetResolver(IDependencyResolver resolver);
11: public static void SetResolver(Func<Type, object> getService, Func<Type, IEnumerable<object>> getServices);
12:
13: public static IDependencyResolver Current { get; }
14: public IDependencyResolver InnerCurrent { get; }
15: }
这个被封装的DependencyResolver(指实现了接口IDependencyResolver的某个类型的类型,不是指DependencyResolver类型的对象,对于后者我会采用“DependencyResolver类型对象”的说法)通过只读属性InnerCurrent表示,而三个InnerSetResolver方法重载用于初始化改属性。静态字段_instance表示当前的DependencyResolver类型对象,静态只读属性Current则表示该对象内部封装的DependencyResolver对象,而它通过三个静态的SetResolver进行初始化。如果我们不曾通过调用DependencyResolver的静态方法SetResolver通过Current属性表示的当前DependencyResolver进行显示设置,该属性默认返回一个DefaultDependencyResolver对象。如下面的代码片断所示,DefaultDependencyResolver是一个实现了IDependencyResolver接口的私有类型,在实现的GetService方法中,它直接通过根据指定的类型以反射的形式创建相应的对象并返回,所以前面我们说DefaultControllerFactory根据解析出来的Controller类型以反射的形式创建对应的实例在这里得到了印证。至于GetServices方法则返回一个空对象集合。
 1: private class DefaultDependencyResolver : IDependencyResolver
 2: {
 3: public object GetService(Type serviceType)
 4: {
 5: if (serviceType.IsInterface || serviceType.IsAbstract)
 6: {
 7: return null;
 8: }
 9: try
10: {
11: return Activator.CreateInstance(serviceType);
12: }
13: catch
14: {
15: return null;
16: }
17: }
18:
19: public IEnumerable<object> GetServices(Type serviceType)
20: {
21: return Enumerable.Empty<object>();
22: }
23: }