首页 > Web开发 > 详细

ASP.NET MVC4学习笔记之Controller激活的扩展

时间:2014-03-23 08:57:05      阅读:552      评论:0      收藏:0      [点我收藏+]

一. 为什么要进行扩展

  在前面的分析中,我们知道默认的Controller激活系统只能实例化无参构造函数的Controller类型,但在某些情况一下,我们希望某些服务的实例能够自动注入到Controller实例中,从而达到服务接口和实现的隔离,减小重复的代码,提高系统的可维护性和灵活性。也就是说我们希望在Controller激活中引入依赖注入。关于依赖注入的概念这里就不解释了,请自行查询相关的资料。基于.net依赖注入框架也有很多,下面的例子主要使用微软企业库的Unity。

  在上一节的分析中,我们知道Controller的激活实际是包括获取IControllerFacotry和IController实例, 在这两个级别都可以引入扩展实现在我们的目的,现在具体来看一下。

一.实列化IControllerFactory  Level

  在这个Level我们知道了路由系统提供的路由信息,当然甚至可以从头到尾自定义实现一个ControllerFactory,包括Controller类型的确定和实例化,但通常没什么必要。我们目标是在Controller实例化阶段注入服务实例,主要还是在Controller实例化阶段。

二. 实列化Controller Level

  在这一阶段,我们已经确定Controller的类型,通过上一节的分析,有三个点我们可以引入依赖注入。我们假设有一个要显示所有Customer信息的页面,在其中应用了仓储模式,在CustomerController实例化进自动注入仓储的实例。

      1. 继承DefaultControllerFactory,重写GetControllerInstance方法。大概的代码如下:

  

bubuko.com,布布扣
public class UnityControllerFactory : DefaultControllerFactory

  {
    public IUnityContainer Container
    {
      get;
      private set;
    }

    public UnityControllerFactory(IUnityContainer container)
    {
      this.Container = container;
    }

    protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
    {
      return (IController)this.Container.Resolve(controllerType);
    }
  }
bubuko.com,布布扣

 

  然后在Global.asax的Application_Start中注册

bubuko.com,布布扣
private void RegisterUnityControllerFactory()

  {
    IUnityContainer container = new UnityContainer();
    container.RegisterType<ICustomerRepository, CustomerRepository>();
    ControllerBuilder.Current.SetControllerFactory(new UnityControllerFactory(container));
  }
bubuko.com,布布扣

 

  2. 自定义实现IControllerActivator。大概的代码如下:

  

bubuko.com,布布扣
public class UnityControllerActivator : IControllerActivator

  {
    public IUnityContainer Container
    {
      get;
      private set;
    }

    public UnityControllerActivator(IUnityContainer c)
    {
      this.Container = c;
    }

    public IController Create(RequestContext requestContext, Type controllerType)
    {
      return (IController)this.Container.Resolve(controllerType);
    }
  }
bubuko.com,布布扣

 

  注册代码:

  

bubuko.com,布布扣
 private void RegisterUnityControllerActivator()

   {
    IUnityContainer container = new UnityContainer();
    container.RegisterType<ICustomerRepository, CustomerRepository>();
    ControllerBuilder.Current.SetControllerFactory(new DefaultControllerFactory(new UnityControllerActivator(container)));
  }
bubuko.com,布布扣

 

  3.自定义实现全局的IDependencyResolver

bubuko.com,布布扣
public class UnityDependencyResolver : IDependencyResolver
    {
        private IUnityContainer Container
        {
            get;
            set;
        }

        public UnityDependencyResolver()
        {
            this.Container = new UnityContainer();
        }

        public UnityDependencyResolver RegisterType<TFrom, TTo>() where TTo : TFrom
        {
            this.Container.RegisterType<TFrom, TTo>();
            return this;
        }

        public object GetService(Type serviceType)
        {
            try
            {
                return this.Container.Resolve(serviceType);
            }
            catch(ResolutionFailedException)
            {
                return null;
            }
        }

        public IEnumerable<object> GetServices(Type serviceType)
        {
            try
            {
                return this.Container.ResolveAll(serviceType);
            }
            catch (ResolutionFailedException)
            {
                return null;
            }
        }
bubuko.com,布布扣

    注册代码:

private void SetDependencyResolver()
        {
            UnityDependencyResolver resolver = new UnityDependencyResolver();
            resolver.RegisterType<ICustomerRepository, CustomerRepository>();
            DependencyResolver.SetResolver(resolver);
        }

 

三.真的要扩展吗?

  天下没有完美的东西,引入一样东西我们必须要充分认识它的优势,也要认清它的副作用。在实际项目中,个人觉得大部分情况是没必要在Controller这个Level引入依赖注入,在Controller的Action中,通常我们要调用业务逻辑服务,业务逻辑的服务接口通常是没必要再引入一层另外的抽象。

  另外,在这里大致总结一下,在Action中大概有两种方式来调用业务逻辑,一种利用Command模式,即把每个Action 对一个Command,在Command中再调用业务逻辑服务.一种是每个Controller包含一个或多个粗粒度的业务包装服务类,每个Action中直接调用一个或多个服务类处理。具体使用那一种模式,应根据你的项目情况来决定,这里不展开细说了。

    最后所有的测试代码可以在这里下载http://files.cnblogs.com/jjyjjyjjy/TestAsp_Net_Mvc_ControllerActivator_DI.rar

ASP.NET MVC4学习笔记之Controller激活的扩展,布布扣,bubuko.com

ASP.NET MVC4学习笔记之Controller激活的扩展

原文:http://www.cnblogs.com/jjyjjyjjy/p/3617583.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!