白话学习MVC(五)Controller的激活

1、概述

  在此系列开篇的时候介绍了MVC的生命周期 , 对于请求的处理,都是将相应的类的方法注册到HttpApplication事件中,经过事件的依次执行从而完成对请求的处理。对于MVC来讲,请求是先 通过路由系统,而后由一个MvcHandler来处理的,当请求到来时,执行此MvcHandler的ProcessRequest方法(由于已将 MvcHandler类的ProcessRequest方法注册到HttpApplication的事件中,因此事件的执行就触发了此方法)。详细请看以前介绍MVC生命周期的两篇博客
  下面咱们就以MVC声明周期为主线,来分析下MVC源码html

public class MvcHandler : IHttpAsyncHandler, IHttpHandler, IRequiresSessionState
{
    protected virtual void ProcessRequest(HttpContext httpContext)
    {
        //使用HttpContextWrapper对HttpContext进行封装,封装的目的是为了解耦以得到可测试性.而后从RequestContext.RouteData中提取Controller名称.
        HttpContextBase httpContext2 = new HttpContextWrapper(httpContext);
        this.ProcessRequest(httpContext2);
    }
    
    protected internal virtual void ProcessRequest(HttpContextBase httpContext)
    {
        IController controller;
        IControllerFactory controllerFactory;
        this.ProcessRequestInit(httpContext, out controller, out controllerFactory);//获取到Controler和ControllerFactory实例,并赋值给局部变量
        try
        {
          //Action的调用,下一篇介绍
//当前Controler对象的Action的建立与执行(执行包括:加载TempData, 建立及执行Action,处理Action返回的ActionResult ,保存TempData数据) controller.Execute(this.RequestContext); } finally { //释放当前Controler对象 controllerFactory.ReleaseController(controller); } } }

 

2、Controller的激活

    从上述代码中能够看出,对Controller激活的相关的操做是经过MvcHandler类的 ProcessRequestInit 方法来执行,而执行完成后,将获取到Controller和ControllerFactory实例!也就是说这 个 this.ProcessRequestInit(httpContext, out controller, out controllerFactory) 方法才是本片博客的旨在,下面就经过这个方法的内部代码来剖析下Controller的激活的机制!缓存

private void ProcessRequestInit(HttpContextBase httpContext, out IController controller, out IControllerFactory factory)
{
   //使用指定的 HTTP 上下文来添加版本标头。如:添加一个Http Header: HTTP/1.1 200 OK   …   X-AspNetMvc-Version: 2.0…
   this.AddVersionHeader(httpContext);
   this.RemoveOptionalRoutingParameters();
//RequestContext.RouteData中提取Controller名称。如:Home/Index的话,就获取到Home string requiredString = this.RequestContext.RouteData.GetRequiredString("controller");
factory
= this.ControllerBuilder.GetControllerFactory();//获取一个用于建立Controller实例的ControllerFactory.默认DefaultControllerFactory controller = factory.CreateController(this.RequestContext, requiredString);//根据ControllerFactory建立Controller对象。

if (controller == null) { throw new InvalidOperationException(string.Format(CultureInfo.CurrentUICulture,MvcResources.ControllerBuilder_FactoryReturnedNull,new object[] { factory.GetType(), requiredString })); } } 因为使用了out关键字,这个方法中的执行过程当中所获得的值,即:赋值给ProcessRequest方法中声明的Controller和ControllerFactory

 显然,上述的代码中这两行代码是重点,代码经过执行一个全局的变量ControllerBuilder的GetControllerFactory方法获得 一个ControllerFactory,而后再经过执行此ControllerFactory的CreateController方法获得 Controller实例!mvc

   factory = this.ControllerBuilder.GetControllerFactory();//获取一个用于建立Controller实例的ControllerFactory.默认DefaultControllerFactory
   controller = factory.CreateController(this.RequestContext, requiredString);//根据ControllerFactory建立Controller对象。

下面就来了解下这两行代码:app

一、factory = this.ControllerBuilder.GetControllerFactory();ide

    this.ControllerBuilder是MvcHandler类的一个属性,属性返回的是MvcHandler类声明的一个 ControllerBuilder类型的字段,属性在返回时会判断当前字段是否为空,若是为空,则调用ControllerBuilder类的静态属性 Current字段,来获取一个ControllerBuilder实例。函数

namespace System.Web.Mvc
{
    public class MvcHandler : IHttpAsyncHandler, IHttpHandler, IRequiresSessionState
    {
        //省略其余成员变量
        private ControllerBuilder _controllerBuilder;
        internal ControllerBuilder ControllerBuilder
        {
            get
            {
                if (_controllerBuilder == null)
                {
                    _controllerBuilder = ControllerBuilder.Current;
                }
                return _controllerBuilder;
            }
            set { _controllerBuilder = value; }
        }

        private void ProcessRequestInit(HttpContextBase httpContext, out IController controller, out IControllerFactory factory)
        { 
            //省略其余代码
            factory = ControllerBuilder.GetControllerFactory();
        }
    }
}
 
_controllerBuilder
= ControllerBuilder.Current;说明ControllerBuilder是由ControllerBuilder类的静态属性Current获取的,接下来再看一下ControllerBuilder类
namespace System.Web.Mvc
{
    public class ControllerBuilder
    {
        //声明静态字段,执行此类的构造函数
        private static ControllerBuilder _instance = new ControllerBuilder();

        private Func<IControllerFactory> _factoryThunk = () => null;
        private HashSet<string> _namespaces = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

        //暂且理解为是封装ControllerFactory的一个类,经过该类的Current属性来获取当前封装的ControllerFactory实例
        private IResolver<IControllerFactory> _serviceResolver;

        public ControllerBuilder()
            : this(null) //: this(null)表示执行带一个参数的构造函数,而且传入的参数为Null
        {
        }

        internal ControllerBuilder(IResolver<IControllerFactory> serviceResolver)
        {
            //若是传入的参数为null,则实例化一个SingleServiceResolver类并赋值给私有字段_serviceResolver。
            _serviceResolver = serviceResolver ?? new SingleServiceResolver<IControllerFactory>(
                                                      () => _factoryThunk(),
                                                      new DefaultControllerFactory { ControllerBuilder = this },
                                                      "ControllerBuilder.GetControllerFactory");
        }

        public static ControllerBuilder Current
        {
            //获取Controller实例
            get { return _instance; }
        }

        public HashSet<string> DefaultNamespaces
        {
            get { return _namespaces; }
        }

        [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Justification = "Calling method multiple times might return different objects.")]
        public IControllerFactory GetControllerFactory()
        {
            //获取ControllerFactory实例
            return _serviceResolver.Current;
        }

        public void SetControllerFactory(IControllerFactory controllerFactory)
        {
            if (controllerFactory == null)
            {
                throw new ArgumentNullException("controllerFactory");
            }

            _factoryThunk = () => controllerFactory;
        }

        public void SetControllerFactory(Type controllerFactoryType)
        {
            if (controllerFactoryType == null)
            {
                throw new ArgumentNullException("controllerFactoryType");
            }
            if (!typeof(IControllerFactory).IsAssignableFrom(controllerFactoryType))
            {
                throw new ArgumentException(
                    String.Format(
                        CultureInfo.CurrentCulture,
                        MvcResources.ControllerBuilder_MissingIControllerFactory,
                        controllerFactoryType),
                    "controllerFactoryType");
            }

            _factoryThunk = delegate
            {
                try
                {
                    return (IControllerFactory)Activator.CreateInstance(controllerFactoryType);
                }
                catch (Exception ex)
                {
                    throw new InvalidOperationException(
                        String.Format(
                            CultureInfo.CurrentCulture,
                            MvcResources.ControllerBuilder_ErrorCreatingControllerFactory,
                            controllerFactoryType),
                        ex);
                }
            };
        }
    }
}

ControllerBuilder
ControllerBuilder

   ControllerBuilder类中有一个静态字段private static ControllerBuilder _instance = new ControllerBuilder();,静态字段是在程序执行前加载的,那么由代码可知,就须要执行该类的构造函数,即执行public ControllerBuilder(): this(null),而其后的: this(null)则表示要去执执行带一个参数的构造函数 ControllerBuilder(IResolver<IControllerFactory> serviceResolver),这个构造函数中首先判断传入的参数是否为空,若是为空的话就实例化一个 SingleServiceResolver<IControllerFactory>对象(暂且理解为封装 ControllerFactory的一个类),并赋值给私有变量_serviceResolver,经过调用_serviceResolver的 Current属性来获取当前封装的ControllerFactory实例。
实例化SingleServiceResolver<IControllerFactory>对象时:学习

public class ControllerBuilder
    {
        //省略其余成员变量
        private Func<IControllerFactory> _factoryThunk = () => null;       

        internal ControllerBuilder(IResolver<IControllerFactory> serviceResolver)
        {
            //若是传入的参数为null,则实例化一个SingleServiceResolver类并赋值给私有字段_serviceResolver。
            _serviceResolver = serviceResolver ?? new SingleServiceResolver<IControllerFactory>(
                                                      () => _factoryThunk(),
                                                      new DefaultControllerFactory { ControllerBuilder = this },
                                                      "ControllerBuilder.GetControllerFactory");
        }

        public void SetControllerFactory(IControllerFactory controllerFactory)
        {
            if (controllerFactory == null)
            {
                throw new ArgumentNullException("controllerFactory");
            }

            _factoryThunk = () => controllerFactory;
        }

        public void SetControllerFactory(Type controllerFactoryType)
        {
            //省略其余代码
            _factoryThunk = delegate
            {
                try
                {
                    return (IControllerFactory)Activator.CreateInstance(controllerFactoryType);
                }
                catch (Exception ex)
                {
                }
            };
        }
    }

ControllerBuilder
ControllerBuilder

   注意,当实例化SingleServiceResolver<IControllerFactory>时,只有第一个参数是变量,默认状况 下传入的是null,那么实例化的该SingleServiceResolver对象的Current属性就返回 DefaultControllerFactory;当调用ControllerBuilder的SetControllerFactroy方法时会对_factoryThunk 赋值一个自定义的ControllerFactory时,那么实例化的该SingleServiceResolver对象的Current属性就返回自定 义的ControllerFactory。因此,此处就是一个扩展点,咱们能够自定义一个ControllerFactory,并经过 ControllerBuilder.Current.SetControllerFactory(...)方法来让程序使用自定的 ControllFatory。这里须要说明一下的是_factoryThunk 是一个无参数、返回值类型为IControllerFactory的委托,而_factoryThunk()则是一个执行这个委托获得的返回值(null、自定义的ControllerFactory)。测试

咱们说了:
  当参数为null时,该实例对象的Current属性返回的是DefaultControllerFactory
  当参数为自定义ControllerBuilder时,该实例对象的Current属性返回的是自定义的ControllerBuilder
由 于以前咱们一直把SingleServiceResolver<IControllerFactory>看成是一个封装 ControllerBuilder的一个类,下面就来看看它究竟是不是封装ControllerBuilder的,而且究竟是如何根据第一个参数的不一样 而决定其Current属性返回值的具体类不一样的。
字体

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;//将此泛型委托赋值给私有变量_currentValueThunk
            _defaultValue = defaultValue;//将此泛型类型赋值给私有变量_defaultValue(当前TService就是IControllerFactory)
            _callerMethodName = callerMethodName;
        }
        
        public TService Current
        {
            //_currentValueThunk()就是第一个参数(无参数的委托)执行以后的返回值
            //_defaultValue就是传入的DefaultControllerFactory实例
            //可见若是第一个参数为空的话,返回的就是DefaultControllerFactory实例;不然就是泛型委托的返回值类型的实例,即自定义的ControllerFactory
            get { return _currentValueFromResolver.Value ?? _currentValueThunk() ?? _defaultValue; }
        }
        private TService GetValueFromResolver()
        {
            //_resolverThunk()返回的就是DefaultDependencyResolver实例
            //在调用IDependencyResolver的扩展方法中的GetService<TService>方法
            TService result = _resolverThunk().GetService<TService>();
            return result;
        } }

   若是上述构造函数中的前两句代码暂且不议(灰色字体就用不到),那么就很是简洁了,即:当构造函数中第一个参数为null,则 Current的属性返回的就是第二个参数的值。反映到当前的建立ControllerFacotory,第一个参数就是自定义的 ControllerFactory(可经过ControllerBuilder的SetControllerFactory添加自定义的 ControllerFactory),第二个参数就是默认的DefaultControllerFactory。
  其实,整个过程灰色字体就是经过IService建立实例(此处IService=IControllerFactory),接下来咱们就来单独的看看被暂且搁置的灰色字体部,分析代码前,先来了解一下的接口和类:
  IDependencyResolver接口中有两个方法,是以类型作为参数经过反射类建立对象,而IDependencyResolver接口还有两个一样功能的泛型扩展方法定义在类DependencyResolverExtensions中;
  DefaultDependencyResolver类实现了IDependencyResolver接口;
  DependencyResolver类则是用来建立【实现IDependencyResolver接口的类的实例】,默认状况建立的是DefaultDependencyResolver类的实例,最终经过DependencyResolver类的静态Current属性可获得建立的实例。
ui

namespace System.Web.Mvc
{
    public class DependencyResolver
    {
        //静态字段,全部程序开始执行时便会自动执行其构造函数。
        private static DependencyResolver _instance = new DependencyResolver();

        private IDependencyResolver _current;
        private CacheDependencyResolver _currentCache;

        public DependencyResolver()
        {
            InnerSetResolver(new DefaultDependencyResolver());
        }

        public void InnerSetResolver(IDependencyResolver resolver)
        {
            _current = resolver;
        }

        public static IDependencyResolver Current
        {
            get { return _instance.InnerCurrent; }
        }

        public IDependencyResolver InnerCurrent
        {
            get { return _current; }
        }

        //内部私有类
        private class DefaultDependencyResolver : IDependencyResolver
        {
            [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "This method might throw exceptions whose type we cannot strongly link against; namely, ActivationException from common service locator")]
            public object GetService(Type serviceType)
            {
                if (serviceType.IsInterface || serviceType.IsAbstract)
                {
                    return null;
                }

                try
                {
                    return Activator.CreateInstance(serviceType);
                }
                catch
                {
                    return null;
                }
            }

            public IEnumerable<object> GetServices(Type serviceType)
            {
                return Enumerable.Empty<object>();
            }
        }

    }
}
DependencyResolver
namespace System.Web.Mvc
{
    public interface IDependencyResolver
    {
        object GetService(Type serviceType);
        IEnumerable<object> GetServices(Type serviceType);
    }
}
IDependencyResolver
namespace System.Web.Mvc
{
    //IDependencyResolver的扩展方法
    public static class DependencyResolverExtensions
    {
        public static TService GetService<TService>(this IDependencyResolver resolver)
        {
            return (TService)resolver.GetService(typeof(TService));
        }

        public static IEnumerable<TService> GetServices<TService>(this IDependencyResolver resolver)
        {
            return resolver.GetServices(typeof(TService)).Cast<TService>();
        }
    }
}
DependencyResolverExtensions

  一、_resolverThunk = () => DependencyResolver.Current;
    DependencyResolver类的静态属性Current默认状况下返回的就是一个DependencyResolver实例,并将该实例做为委托_resolverThunk的返回值。
  二、_currentValueFromResolver = new Lazy<TService>(GetValueFromResolver);

    Lazy表示延迟执行,当执行lazy实例的value属性时候才执行Lazy构造函数中的方法,方法的返回值就是value属性的值。此处表示当调用_currentValueFromResolver的value属性时,就会执行方法GetValueFromResolver(),在方法内调用了执行_resolverThunk委托获得的DefaultDependencyResolver实例 的扩展方法GetService<TService>经过反射建立TService的实例,并做为返回值。而方法的返回值就是Lazy的value属性的值。
  因为ControllerBuilder构造函数中实例化SingleServiceResolver<TService>类型时,TService=IControllerFactory接口,因此调用泛型方法GetService<TService>()方法时,传入的类型是接口IControllerFactory,而方法内部的判断若是是接口或抽象类时候就返回null,即: _currentValueFromResolver.Value=null 。那么此处的灰色部分执行的最终结果就是_currentValueFromResolver.Value=null,在这里没有其到做用!

 

  以 上介绍了factory = this.ControllerBuilder.GetControllerFactory();中的ControllerBuilder如何实例化,并 如何返回一个ControllerFactory实例。有了ControllerFactory以后,那么就该调用ControllerFactory的 CreateController(RequestContext requestContext, string controllerName);方法(根据第二个参数经过反射实例化一个Controller,并返回)。

// 非重点补充:ControllerBuilder的 DefaultNamespaces属性

        public HashSet<string> DefaultNamespaces
        {
            get { return _namespaces; }
        }

      //HashSet<T>是一组不重复出现且无特定顺序的元素集合
  //此属性的功能正如其名字DefaultNamespaces,默认的命名空间。即:当存在两个同名的Controller且命名空间不一样,这中状况是容许的,可是MVC在激活Controller时会分不清到底要激活那个Controller,而此属性的目的就是处理这种状况的,他能让MVC激活DefaultNamespaces设置的命名空间下的Controller;除此以外,还有一处能够解决此问题,那就是路由注册时的MapRoute方法的参数string[] namespaces 。当二者同时存在时,后者优先。

非重点补充
非重点补充

注:以上所说的ControllerFactory泛指实现了IControllerFactory接口的类;

二、controller = factory.CreateController(this.RequestContext, requiredString);

   此行代码,利用上一句获得一个ControllerFactory实例,再将【请求上下文】和【要激活的Controller的字符串】做为参数来调用 ControllerFactory类的CreateController方法,以此建立Controller实例,并返回!  即:经过ControllerFactory类来完成对Controller的激活,那么对于此行代码的解析就成了对ControllerFactory 类的分析!

  由于ControllerFactory泛指实现了IControllerFactory的类,因此就从IControllerFactory接口开始介绍:

    public interface IControllerFactory
    {
        //获取Controller实例
        IController CreateController(RequestContext requestContext, string controllerName);
        //返回值为SessionStateBehavior枚举,表示请求处理过程当中会话状态支持的模式
        SessionStateBehavior GetControllerSessionBehavior(RequestContext requestContext, string controllerName);
        //释放Controller实例
        void ReleaseController(IController controller);
    }
public enum SessionStateBehavior
{
Default,使用默认 ASP.NET 逻辑来肯定请求的会话状态行为。
Required,为请求启用彻底的读写会话状态行为。
ReadOnly,为请求启用只读会话状态。
Disabled 禁用会话状态。
}

  咱们能够实现此IControllerFactory接 口,再经过ControllerBuilder.Current.SetControllerBuilder()添加自定义的 ControllerBuilder;而后默认状况下,MVC使用的是DefaultControllerFactory,接下来就看看 DefaultControllerFactory中是如何实现IControllerFactory接口的。

    public class DefaultControllerFactory : IControllerFactory
    {
        //省略其余成员
        private IResolver<IControllerActivator> _activatorResolver;
        private IControllerActivator _controllerActivator;
        private ControllerBuilder _controllerBuilder;
       
        public DefaultControllerFactory()
            : this(null, null, null)
        {
        }
        //利用自定义的ControllerActivator时,经过在ControllerBuilder中实例化DefaultControllerFactory时出入自定义ControllerActivator为参数 public DefaultControllerFactory(IControllerActivator controllerActivator)
            : this(controllerActivator, null, null)
        {
        }

        internal DefaultControllerFactory(IControllerActivator controllerActivator, 
            IResolver<IControllerActivator> activatorResolver, IDependencyResolver dependencyResolver)
        {
            //controllerActivator类才是最终经过反射建立Controller实例的
            //重点:这里对判断controllerActivator的判断,只有当为空时才使用默认的DefaultControllerActivator
            //因此,这里又有一个扩展,经过实现IControllerActivator接口建立自定义ControllerActivator
            //在实例化DefaultControllerFactory时传入自定义ControllerActivator做为参数
            if (controllerActivator != null)
            {
                _controllerActivator = controllerActivator;
            }
            else
            {
          //这里的实例化SingleServiceResolver时,传入的又是接口,如上讲解的SingleServiceResolver类中灰色字体部分没有起到做用!
//此处第一个参数是个常量且为null,因此此SingleServiceResolver<>的Current属性只能返回DefaultControllerActivator实例 _activatorResolver = activatorResolver ?? new SingleServiceResolver<IControllerActivator>( () => null, new DefaultControllerActivator(dependencyResolver), "DefaultControllerFactory constructor"); } } //在ControllerBuilder中实例化DefaultControllerFactory时,赋值。(参见ControllerBuilder类的构造函数) internal ControllerBuilder ControllerBuilder { get { return _controllerBuilder ?? ControllerBuilder.Current; } set { _controllerBuilder = value; } } private IControllerActivator ControllerActivator { get { //当_controllerActivator为空时,才去_activatorResolver中获取DefaultControllerActivator实例做为ControllerActivator if (_controllerActivator != null) { return _controllerActivator; } _controllerActivator = _activatorResolver.Current; return _controllerActivator; } } public virtual IController CreateController(RequestContext requestContext, string controllerName) { //省略其余代码        //根据字符串【类型名】和【上下文中的命名空间】建立Controller的类型 Type controllerType = GetControllerType(requestContext, controllerName); IController controller = GetControllerInstance(requestContext, controllerType);//根据类型建立Controller实例 return controller; } protected internal virtual IController GetControllerInstance(RequestContext requestContext, Type controllerType) { //省略其余代码        //调用ControllerActivator实例的Create经过反射建立实例。默认为DefaultControllerActivator return ControllerActivator.Create(requestContext, controllerType); } }
private class DefaultControllerActivator : IControllerActivator
        {
            private Func<IDependencyResolver> _resolverThunk;

            public DefaultControllerActivator()
                : this(null)
            {
            }

            public DefaultControllerActivator(IDependencyResolver resolver)
            {
                if (resolver == null)
                {
                    _resolverThunk = () => DependencyResolver.Current;
                }
                else
                {
                    _resolverThunk = () => resolver;
                }
            }

            public IController Create(RequestContext requestContext, Type controllerType)
            {
                try
                {
                    //若是 符号【??】前面的部分为空,则经过反射建立实例
                    return (IController)(_resolverThunk().GetService(controllerType) ?? Activator.CreateInstance(controllerType));
                }
            }
        }

DefaultControllerActivator
DefaultControllerActivator

  上述代码中注释部分包含【Controller激活的步骤】和又一扩展点【建立自定ControllerActivator 】,因此略显混乱。下面咱们就来用文字叙述一下这两部分:
1、根据ControllerBuilder中实例化DefaultControllerFactory时,利用的是无参数的构造函数,可是此构造函数又带着三个为null的参数执行有三个参数的构造函数,因此默认状况下私有字段_controllerActivator就是null,那么执行Current来获取ControllerActivator时,就将DefaultControllerActivator实例赋值给_controllerActivator字段,以后再调用该实例的Create方法,在方法内部利用反射建立Controller实例。
2、正如咱们所知,最后是经过一个ControllerActivator的Create方法,根据参数【请求上下文】【Controller类型】来实现建立Controller实例的。因此,咱们就能够经过实现IControllerActivator接口来建立自定义的ControllerActivator。建立自定义的ControllerActivator没问题,那么
如何使程序去利用自定义的ControllerActivator呢?
  答:
注意DefaultControllerFactory含有三个参数的构造函数,首先会判断第一个参数c
ontrollerActivator若是不为空,则将参数赋值给私有变量_controllerActivator。当经过Current获取当前ControllerActivator时,判断 私有变量_controllerActivator是否为空,若是不为空,则直接返回。由此,咱们就能够在实例化DefaultControllerFactory时为第一个参数传入自定义ControllerActivator实例,即经过实例化含一个参数DefaultControllerFactory构造函数,进而再去执行三个参数的构造函数。
又如何执行DefaultControllerFactory带一个参数的构造函数并传入自定义ControllerActivator实例做为参数呢?
   答:经过在Application_Start方法中经过ControllerBuilder的SetControllerBuilder方法的参数中 传入new DefaultControllerFactory(new MyControllerActivator())为参数。即:MyControllerActivator类是实现了 IControllerActivator接口的自定义ControllerActivator

ControllerBuilder controllerBulder = ControllerBuilder.Current;
controllerBulder.SetControllerFactory(new DefaultControllerFactory(new MyControllerActivator()));

 

   以上就是第二句代码controller = factory.CreateController(this.RequestContext, requiredString);获取Controller实例的所有,其中又对发现了一个扩展点【自定义ControllerActivator】和如 何让程序使用自定义的ControllerActivator

 3、Controller的释放

  由本篇博客概述中的MvcHandler类中,能够看出在try finally块的fianlly中经过controllerFactory.ReleaseController(controller); 即:当前ControllerFactory的ReleseController方法来实现释放,咱们就来看看默认的DefaultControllerFactory中的ReleseController方法

    public class DefaultControllerFactory : IControllerFactory
    {
        //省略其余成员

        public virtual void ReleaseController(IController controller)
        {
            IDisposable disposable = controller as IDisposable;
            if (disposable != null)
            {
                disposable.Dispose();
            }
        }
    }

 

以上本篇博客Controller激活的所有内容!!!

 

 

 

 对于Controller激活的相关知识中遗留的问题有:
一、Controller类型的缓存

二、会话状态行为的控制

三、DependencyResoolver类(已更新)

若有兴趣的话,对于此三部分的问题能够到Artech的博客MVC系列【How ASP.NET MVC Works】Controller激活部分学习下!

更新  2013-10-19:已在ContrllerBuilder建立ControllerFactory部分添加对DependencyResoolver类的介绍!

相关文章
相关标签/搜索