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

注:本文所指MVC框架特指Asp.Net MVC 3.0,文中若有不当之处,请多加包涵,谢谢!

 尊重他人原创,转载请务必注明来自http://www.cnblogs.com/Raoh/archive/2013/03/27/AspNetMvc_IOC.html

我们在做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

posted @ 2013-03-27 15:19  大悟飞天  阅读(1518)  评论(1编辑  收藏  举报