ASP.NET MVC中使用Unity进行依赖注入的三种方式

在ASP.NET MVC中使用Unity进行依赖注入的三种方式

2013-12-15 21:07 by 小白哥哥, 146 阅读, 0 评论, 收藏编辑

在ASP.NET MVC4中,为了在解开Controller和Model的耦合,我们通常需要在Controller激活系统中引入IoC,用于处理用户请求的Controller,让Controller依赖于ModelRepository的抽象而不是它的实现。

我们可以在三个阶段使用IoC实现上面所说的解耦操作,首先需要简单介绍一下默认情况下Controller的激活过程:

  1. 用户发送请求黑ASP.NET,路由系统对请求进行解析,根据注册的路由规则对请求进行匹配,解析出Controller和Action的名称等信息。
  2. 将解析出的信息交给一个MvcRouteHandler对象进行处理,MvcHttpHandler中存在以个ControllerFactory成员,如果构造函数中没有提供一个实现IControllerFactory接口的对象,则默认构造函数通过调用ControllerBuilder.Current.GetControllerFactory()获取一个这样的对象。
  3. 系统调用上文对象中德GetHttpHandler获得了一个实现了IHttpHandler接口的MvcHandler对象最终处理请求。
  4. 在MvcHandler中调用BeginProcessRequest方法继续处理请求,方法中从1中解析的信息中获得Controller和Action的信息,而后利用2种的IControllerFactory对象激活Controller对象,并最终执行相应的Action。

第一种方法

由上文2种可知,我们可以创建自己的IControllerFactory对象实现依赖注入,然而我们可以通过直接继承DefaultControllerFactory并重写GetControllerInstance方法来实现,这样可以免去重新实现其他一些功能的工作。

以下是使用Unity创建的继承自DefaultControllerFactory的UnityControllerFactory的简单示例:

 
  1. namespace UnitySample
  2. {
  3. public class UnityControllerFactory:DefaultControllerFactory
  4. {
  5. private IUnityContainer container;
  6. public UnityControllerFactory(IUnityContainer container)
  7. {
  8. this.container = container;
  9. }
  10. protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
  11. {
  12. return null == controllerType ? null : (IController)this.container.Resolve(controllerType);
  13. //return base.GetControllerInstance(requestContext, controllerType);
  14. }
  15. }
  16. }

我们可以在App_Start中使用ControllerBuilder设置系统使用这个ControllerFactory

 
  1. IUnityContainer container = new UnityContainer();
  2. container.RegisterType<IXXXRepository, XXXRepository>();
  3. UnityControllerFactory factory = new UnityControllerFactory(container);
  4. ControllerBuilder.Current.SetControllerFactory(factory);
 

第二种方法

上文中继承的DefaultControllerFactory中,使用一个ControllerActivator的成员来实现对Controller的激活,如果创建对象中没有提供一个IControllerActivator对象,则提供一个默认实现了IControllerActivator的DefaultControllerActivator对象这个类型,这个接口中存在用于创建Controller对象的Create方法,在DefaultControllerFactory中有存在一个IControllerActivator类型的构造方法来制定它。所以我们可以使用一个自定义的实现自IControllerActivator借口的对象来进行依赖注入。

 
  1. namespace UnitySample
  2. {
  3. public class UnityControllerActivator:IControllerActivator
  4. {
  5. private IUnityContainer container;
  6. public UnityControllerActivator(IUnityContainer container)
  7. {
  8. this.container = container;
  9. }
  10. public IController Create(RequestContext requestContext, Type controllerType)
  11. {
  12. return controllerType == null ? null : (IController)container.RegisterType(controllerType);
  13. }
  14. }
  15. }

修改方法1中在App_Start中的代码,使用这个ControllerActivator:

 
  1. IUnityContainer container = new UnityContainer();
  2. container.RegisterType<IXXXRepository, XXXRepository>();
  3. //UnityControllerFactory factory = new UnityControllerFactory(container);
  4. IControllerActivator controllerActivator = new UnityControllerActivator(container);
  5. DefaultControllerFactory defaultFactory = new DefaultControllerFactory(controllerActivator);
  6. ControllerBuilder.Current.SetControllerFactory(defaultFactory);

第三种方法

如同DefaultControllerFactory类中一样,在DefaultControllerActivator中也存在一个包含一个参数(类型为IDependencyResolver)的构造方法和一个没有参数的构造方法,默认情况下DefaultControlerFactory使用无参构造函数实例化一个DefaultControllerActivator对象,这种情况下提供一个默认的IDependencyResolver对象。所以我们就同样可以使用一个自定义的IDependencyResolver类实现依赖注入。在IDependencyResolver接口中存在方法GetService和GetServices来对具体的类型进行解析

 
  1. namespace UnitySample
  2. {
  3. public class UnityDependencyResolver:IDependencyResolver
  4. {
  5. private IUnityContainer container;
  6. public UnityDependencyResolver(IUnityContainer container)
  7. {
  8. this.container = container;
  9. }
  10. public object GetService(Type serviceType)
  11. {
  12. return container.Resolve(serviceType);
  13. }
  14. public IEnumerable<object> GetServices(Type serviceType)
  15. {
  16. return container.ResolveAll(serviceType);
  17. }
  18. }
  19. }

修改App_Start中的方法,使用这个自定义的DependencyResolver:

 
  1. IUnityContainer container = new UnityContainer();
  2. container.RegisterType<IXXXRepository, XXXRepository>();
  3. UnityDependencyResolver resolver = new UnityDependencyResolver(container);
  4. DependencyResolver.SetResolver(resolver);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值