MVC5 Controller简要创建过程(1):ControllerFactory的创建

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

首先看MvcHandler:

 1 public class MvcHandler : IHttpAsyncHandler, IHttpHandler, IRequiresSessionState

 2     {

 3           //...

 4           private ControllerBuilder _controllerBuilder;

 5           internal ControllerBuilder ControllerBuilder

 6         {

 7             get

 8             {

 9                 if (_controllerBuilder == null)

10                 {

11                     _controllerBuilder = ControllerBuilder.Current; 12                 }

13                 return _controllerBuilder;

14             }

15             set { _controllerBuilder = value; }

16         }

17            //...

18            protected internal virtual void ProcessRequest(HttpContextBase httpContext)

19         {

20             IController controller;

21             IControllerFactory factory;

22             ProcessRequestInit(httpContext, out controller, out factory); 23 

24             try

25             {

26                 controller.Execute(RequestContext);

27             }

28             finally

29             {

30                 factory.ReleaseController(controller);

31             }

32         }

33 

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

35         {

36             // ...

37             // Get the controller type

38             string controllerName = RequestContext.RouteData.GetRequiredString("controller");

39 

40             // Instantiate the controller and call Execute

41             factory = ControllerBuilder.GetControllerFactory(); 42             controller = factory.CreateController(RequestContext, controllerName); 43             //...

44         }
}

简而言之,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的整个创建过程就是这样了。

你可能感兴趣的:(controller)