简单剖析Asp.Net MVC 源码中的三个IOC注入点

来源:互联网 发布:华为 待遇 知乎 编辑:程序博客网 时间:2024/06/14 11:47

我们在做Asp.Net MVC依赖注入的时候,注入点主要有三个地方,分列如下:
1.实现了IControllerFactory接口的DefaultControllerFactory;
2.实现了IDependencyResolver接口的DefaultDependencyResolver;
3.实现了IControllerActivator接口的DefaultControllerActivator;

下面,我们简单剖析下这三个注入点的框架源码:
首先,MVC框架的Controller激活(实例化)过程是由IControllerFactory实现的,
IControllerFactory的源码如下:

public interface IControllerFactory {        IController CreateController(RequestContext requestContext, string controllerName);        SessionStateBehavior GetControllerSessionBehavior(RequestContext requestContext, string controllerName);        void ReleaseController(IController controller);}

MVC框架中该接口的默认实现是DefaultControllerFactory,由DefaultControllerFactory的GetControllerInstance方法返回一个Controller实例(注意:可以将这里做为第一个依赖注入点),该方法的源码实现如下:

复制代码
protected internal virtual IController GetControllerInstance(RequestContext requestContext, Type controllerType) {            if (controllerType == null) {                throw new HttpException(404,                    String.Format(                        CultureInfo.CurrentCulture,                        MvcResources.DefaultControllerFactory_NoControllerFound,                        requestContext.HttpContext.Request.Path));            }            if (!typeof(IController).IsAssignableFrom(controllerType)) {                throw new ArgumentException(                    String.Format(                        CultureInfo.CurrentCulture,                        MvcResources.DefaultControllerFactory_TypeDoesNotSubclassControllerBase,                        controllerType),                    "controllerType");            }            return ControllerActivator.Create(requestContext, controllerType);}
复制代码

跟踪源码,我们会发现,该方法中的ControllerActivator定义如下:

复制代码
private IControllerActivator ControllerActivator {            get {                if (_controllerActivator != null) {                    return _controllerActivator;                }                _controllerActivator = _activatorResolver.Current;                return _controllerActivator;            }        }
复制代码

跟踪到这里,可以发现该方法的默认实现需要一个IControllerActivator,而其实现指向_activatorResolver.Current,继续跟踪源码,发现_activatorResolver是在DefaultControllerFactory的构造函数中实例化的,其默认指向SingleServiceResolver<IControllerActivator>,其源码如下:

复制代码
internal DefaultControllerFactory(IControllerActivator controllerActivator, IResolver<IControllerActivator> activatorResolver, IDependencyResolver dependencyResolver) {            if (controllerActivator != null) {                _controllerActivator = controllerActivator;            }            else {                _activatorResolver = activatorResolver ?? new SingleServiceResolver<IControllerActivator>(                    () => null,                    new DefaultControllerActivator(dependencyResolver),                    "DefaultControllerFactory contstructor"                );            }        }
复制代码

其中SingleServiceResolver<IControllerActivator>构造函数中的第二个参数,new DefaultControllerActivator(dependencyResolver),就是_activatorResolver.Current,也就是IControllerActivator的默认实现,IControllerActivator的源码如下:

public interface IControllerActivator {        IController Create(RequestContext requestContext, Type controllerType);}

该接口仅仅包含一个返回IController的Create方法。(注意:可以将这里做为第二个依赖注入点)

回头来看看DefaultControllerActivator的源码如下:

复制代码
private class DefaultControllerActivator : IControllerActivator {            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));                }                catch (Exception ex) {                    throw new InvalidOperationException(                        String.Format(                            CultureInfo.CurrentCulture,                            MvcResources.DefaultControllerFactory_ErrorCreatingController,                            controllerType),                        ex);                }            }        }
复制代码

阅读源码,我们会发现,该方法需要一个IDependencyResolver,IDependencyResolver的源码如下:

public interface IDependencyResolver {        object GetService(Type serviceType);        IEnumerable<object> GetServices(Type serviceType);}

而在DefaultControllerActivator的构造函数中,IDependencyResolver指向DependencyResolver.Current,通过跟踪代码我们会发现DependencyResolver.Current最终指向DefaultDependencyResolver的实例,框架中IDependencyResolver的默认实现就是DefaultDependencyResolver,其源码如下:

复制代码
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) {                try {                    return Activator.CreateInstance(serviceType);                }                catch {                    return null;                }            }            public IEnumerable<object> GetServices(Type serviceType) {                return Enumerable.Empty<object>();            }        }
复制代码

最终由DefaultDependencyResolver的GetService返回一个Controller实例。(注意:可以将这里做为第三个依赖注入点)

后面,我会写一些代码示例,简单演示对这三个IOC注入点进行注入。

来自http://www.cnblogs.com/Raoh/archive/2013/03/27/AspNetMvc_IOC.html


0 0
原创粉丝点击