简单剖析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
- 简单剖析Asp.Net MVC 源码中的三个IOC注入点
- 简单剖析Asp.Net MVC 源码中的三个IOC注入点
- MVC三个IOC注入点之Ninject使用示例
- ASP.NET MVC中的依赖倒置IOC/依赖注入DI, (MircroSoft.Practices.Unity)与asp.net mvc 3的融合
- ASP.NET MVC学习笔记-MVC运行机制之源码剖析
- Asp.net MVC 使用Autofac的简单使用 IOC
- 【C#MVC】.NET中的IOC--Autofac简单使用
- Ninject--ASP.NET MVC 3中的依赖注入容器
- 17+个ASP.NET MVC扩展点【附源码】
- ASP.NET MVC IOC之Unity攻略
- ASP.NET MVC IOC 之Ninject攻略
- ASP.NET MVC IOC 之Ninject攻略
- ASP.NET MVC IOC 之AutoFac攻略
- ASP.NET MVC IoC处理方式
- ASP.NET MVC IOC 之Ninject攻略
- ASP.NET MVC IOC 之AutoFac攻略
- ASP.NET MVC IOC 之AutoFac攻略
- ASP.NET MVC IOC 之AutoFac攻略
- 三层架构的入门实例讲解
- 一个 bat
- 玩转骰子
- main 函数执行前、后执行的代码
- What is "Data Locality"
- 简单剖析Asp.Net MVC 源码中的三个IOC注入点
- Windows7保护眼睛颜色设置方法
- normalize.css v3.0.0 源码
- 张艺谋望执导合拍片《长城》 华谊联手传奇出品
- 最新版ffmpeg源码分析一:框架
- 常用查找与排序方法
- iOS 使用FMDB进行数据库操作
- fopen()引发的坑爹错误
- Working with FBX SDK (1)