一. 为什么要进行扩展

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

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

一.实列化IControllerFactory  Level

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

二. 实列化Controller Level

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

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

  

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);
    }
  }

  然后在Global.asax的Application_Start中注册

private void RegisterUnityControllerFactory()

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

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

  

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);
    }
  }

  注册代码:

  

 private void RegisterUnityControllerActivator()

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

  3.自定义实现全局的IDependencyResolver

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;
}
}

    注册代码:

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激活的扩展的更多相关文章

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

    一. 高层相关类说明 当路由系统根据请求Url收集路由信息后,下一步就要将路由信息传给Controller激活系统,Controller激活系统负责实现了IController接口的Controlle ...

  2. ASP.NET MVC 学习笔记-7.自定义配置信息 ASP.NET MVC 学习笔记-6.异步控制器 ASP.NET MVC 学习笔记-5.Controller与View的数据传递 ASP.NET MVC 学习笔记-4.ASP.NET MVC中Ajax的应用 ASP.NET MVC 学习笔记-3.面向对象设计原则

    ASP.NET MVC 学习笔记-7.自定义配置信息   ASP.NET程序中的web.config文件中,在appSettings这个配置节中能够保存一些配置,比如, 1 <appSettin ...

  3. asp.net mvc4 学习笔记一(基本原理)

    做了8年的asp.net webform,用过MVVM但还没用过MVC , 虽然项目不用MVC,但是还是想了解一下,今天第二天学习,以下是学习心得. VS2012默认带有asp.net mvc3和as ...

  4. ASP.NET MVC4学习笔记路由系统概念与应用篇

    一.概念 1.路由是计算机网络中的一个技术概念,表示把数据包从一个网段转发至另一网段.ASP.NET中的路由系统作用类似,其作用是把请求Url映射到相应的"资源"上,资源可以是一段 ...

  5. ASP.NET MVC4学习笔记之总体概述

    断断续续使用ASP.NET MVC框架也有一年多了,也算积累了一些经验,唉,一直想写一些笔记好好总结一下,人太懒不想动笔,今天终于决定开始.希望自己能坚持下去. 这篇文章大体介绍ASP.NET MVC ...

  6. ASP.NET MVC5学习笔记之Controller同步执行架构分析

    在开始之前,声明一下,由于ASP.NET MVC5正式发布了,后面的分析将基于ASP.NET MVC5最新的源代码.在前面的内容我们分析了怎样根据路由信息来确定Controller的类型,并最终生成C ...

  7. ASP.NET MVC4学习笔记路由系统实现

    一.路由实现 路由系统实际是一个实现了ASP.NET IHttpModule接口的模块,通过注册HttpApplication的PostResolveRequestCache 事件对Url路由处理.总 ...

  8. ASP.NET MVC4学习笔记

    一.MVC简介

  9. ASP.NET MVC5学习笔记之Controller执行ControllerDescriptor和ActionDescriptor

    一. ControllerDescriptor说明 ControllerDescriptor是一个抽象类,它定义的接口代码如下: public abstract class ControllerDes ...

随机推荐

  1. (easy)LeetCode 202.Happy Number

    Write an algorithm to determine if a number is "happy". A happy number is a number defined ...

  2. 【转】find命令

    Linux中find常见用法示例·find path -option [ -print ] [ -exec -ok command ] {} \;find命令的参数: pathname: find命令 ...

  3. 关闭linux下的使用的端口

    lsof -P -n -i kill pid 另外防火墙 iptables之类的也可以关闭端口

  4. SQL SERVER树型数据处理时,函数递归调用问题,查询根节点,子节点函数

    /* 标题:查询指定节点及其所有子节点的函数 作者:爱新觉罗.毓华(十八年风雨,守得冰山雪莲花开) 时间:2008-05-12 地点:广东深圳 */ ) , pid ) , name )) ' , n ...

  5. Effective Modern C++翻译(7)-条款6:当auto推导出意外的类型时,使用显式的类型初始化语义

    条款6:当auto推导出意外的类型时,使用显式的类型初始化语义 条款5解释了使用auto来声明变量比使用精确的类型声明多了了很多的技术优势,但有的时候,当你想要zag的时候,auto可能会推导出了zi ...

  6. 百度富文本编辑器UEditor安装配置全过程

    网站开发时富文本编辑器是必不可少的,他可以让用户自行编辑内容的样式然后上传到后台!下面我们来介绍如何安装使用百度富文本编辑器 一.下载并且设置百度富文本编辑器的样式     你可以去百度UEditor ...

  7. 博客中 Flex4/Flash mp3音乐播放器实例 含演示地址

    要求 必备知识 本文要求基本了解 Adobe Flex编程知识和JAVA基础知识. 开发环境 MyEclipse10/Flash Builder4.6/Flash Player11及以上 演示地址 演 ...

  8. 【测试】模拟一个全表扫描的sql,对其进行优化走索引,并且将执行计划稳定到baseLine。

    ①创建表t3: SQL> create table t3 (id int); Table created. SQL; rows created. ②开启自动捕获并修改时间格式: SQL> ...

  9. 使用JAR命令打EAR包

    恩,我又得了一个发布应用的活,常常使用JAR命令来打EAR包,所以下面记录一下,以免忘记! 前提条件如下: 1)我的WEB服务器是WebLogic Server (版本是: 10.3.6.0) 2)假 ...

  10. 【HTML/XML 9】XML中的DTD文件

    导读:DTD是Document type definition(文档类型定义的缩写),是一套关于标记符的语法规则,它是XML文件的验证机制,数以XML文件的组成部分.XML文档是一种描述标记语言的语言 ...