1.控制反转

控制反转(Inversion of Control,IoC),简言之就是代码的控制器交由系统控制,而不是在代码内部,通过IoC,消除组件或者模块间的直接依赖,使得软件系统的开发更具柔性和扩展性。控制反转的典型应用体现在框架系统的设计上,是框架系统的基本特征,不管是.NET Framework抑或是Java Framework都是建立在控制反转的思想基础之上。

控制反转很多时候被看做是依赖倒置原则的一个同义词,其概念产生的背景大概来源于框架系统的设计,例如.NET Framework就是一个庞大的框架(Framework)系统。在.NET Framework大平台上可以很容易地构建ASP.NET Web应用、Silverlight应用、Windows Phone应用或者Window Azure Cloud应用。很多时候,基于.NET Framework构建自定义系统的方式就是对.NET Framework本身的扩展,调用框架提供的基础API,扩展自定义的系统功能和行为。然而,不管如何新建或者扩展自定义功能,代码执行的最终控制权还是回到框架中执行,再交回应用程序。黄忠诚先生曾经在Object Builder Application Block一文中给出一个较为贴切的举例,就是在Window From应用程序中,当Application.Run调用之后,程序的控制权交由Windows Froms Framework上。所以,控制反转更强调控制权的反转,体现了控制流程的依赖倒置,所以从这个意义上来说,控制反转是依赖倒置的特例。

2.依赖注入

依赖注入(Dependency Injection,DI),早见于Martin Flower的Inversion of Control Containers and the Dependency Injection pattern一文,其定义可概括为:

客户类依赖于服务类的抽象接口,并在运行时根据上下文环境,由其他组件(例如DI容器)实例化具体的服务类实例,将其注入到客户类的运行时环境,实现客户类与服务类实例之间松散的耦合关系。

(1)常见的三种注入方式

简单而言,依赖注入的方式被总结为以下三种。

  • 接口注入(Interface Injection),将对象间的关系转移到一个接口,以接口注入控制。

首先定义注入的接口:

public interface IRunnerProvider

{

void Run(Action action);

}

为注入的接口实现不同环境下的注入提供器,本例的系统是一个后台处理程序提供了运行环境的多种可能,默认情况下将运行于单独的线程,或者通过独立的Windows Service进程运行,那么需要为不同的情况实现不同的提供器,例如:

public class DefaultRunnerProvider : IRunnerProvider

{

#region IRunnerProvider Members

public void Run(Action action)

{

var thread = new Thread(() => action());

thread.Start();

}

#endregion

}

对于后台服务的Host类,通过配置获取注入的接口实例,而Run方法的执行过程则被注入了接口所定义的逻辑,该逻辑由上下文配置所定义:

public class RunnerHost : IDisposable

{

IRunnerProvider provider = null;

public RunnerHost()

{

// Get Provider by configuration

provider = GetProvider(config.Host.Provider.Name);

}

public void Run()

{

if (provider != null)

{

provider.Run(() =>

{

// exceute logic in this provider, if provider is DefualtRunnerProvider,

// then this logic will run in a new thread context.

});

}

}

}

接口注入,为无须重新编译即可修改注入逻辑提供了可能,GetProvider方法完全可以通过读取配置文件的config.Host.Provider.Name内容,来动态地创建对应的Provider,从而动态地改变BackgroundHost的Run()行为。

  • 构造器注入(Constructor Injection),客户类在类型构造时,将服务类实例以构造函数参数的形式传递给客户端,因此服务类实例一旦注入将不可修改。

public class PicWorker

{

}

public class PicClient

{

private PicWorker worker;

public PicClient(PicWorker worker)

{

// 通过构造器注入

this.worker = worker;

}

}

  • 属性注入(Setter Injection),通过客户类属性设置的方式,将服务器类实例在运行时设定为客户类属性,相较构造器注入方式,属性注入提供了改写服务器类实例的可能。

public class PicClient

{

private PicWorker worker;

// 通过属性注入

public PicWorker Woker

{

get { return this.worker; }

set { this.worker = value; }

}

}

另外,在.NET平台下,除了Martin Flower大师提出的三种注入方式之外,还有一种更优雅的选择,那就是依靠.NET特有的Attribute实现,以ASP .NET MVC中的Action Filter为例:

[HttpPost]

public ActionResult Register(RegisterModel model)

{

// 省略注册过程

return View(model);

}

其中,HttpPostAttribute就是通过Attribute方式为Register Action注入了自动检查Post请求的逻辑,同样的注入方式广泛存在于ASP .NET MVC的很多Filter逻辑中。

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]

public sealed class HttpPostAttribute : ActionMethodSelectorAttribute

{

// Fields

private static readonly AcceptVerbsAttribute _innerAttribute = new AcceptVerbsAttribute(HttpVerbs.Post);

// Methods

public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo)

{

return _innerAttribute.IsValidForRequest(controllerContext, methodInfo);

}

}

关于Attribute的详细内容,请参考8.3节“历史纠葛:特性和属性”,其中的TrimAttribute特性正是应用Attribute注入进行属性Trim过滤处理的典型应用。

转自:http://www.cnblogs.com/jyshis/archive/2011/09/15/2177279.html

解构控制反转(IoC)和依赖注入(DI)的更多相关文章

  1. 控制反转(Ioc)和依赖注入(DI)

    控制反转IOC, 全称 “Inversion of Control”.依赖注入DI, 全称 “Dependency Injection”. 面向的问题:软件开发中,为了降低模块间.类间的耦合度,提倡基 ...

  2. 控制反转IOC与依赖注入DI

    理解 IOC  http://www.cnblogs.com/zhangchenliang/archive/2013/01/08/2850970.html IOC 相关实例      的http:// ...

  3. iOS控制反转(IoC)与依赖注入(DI)的实现

    背景 最近接触了一段时间的SpringMVC,对其控制反转(IoC)和依赖注入(DI)印象深刻,此后便一直在思考如何使用OC语言较好的实现这两个功能.Java语言自带的注解特性为IoC和DI带来了极大 ...

  4. 轻松学,浅析依赖倒置(DIP)、控制反转(IOC)和依赖注入(DI) 依赖注入和控制反转的理解,写的太好了。

    轻松学,浅析依赖倒置(DIP).控制反转(IOC)和依赖注入(DI) 2017年07月13日 22:04:39 frank909 阅读数:14269更多 所属专栏: Java 反射基础知识与实战   ...

  5. 控制反转IOC与依赖注入DI【转】

    转自:http://my.oschina.net/1pei/blog/492601 一直对控制反转.依赖注入不太明白,看到这篇文章感觉有点懂了,介绍的很详细. 1. IoC理论的背景我们都知道,在采用 ...

  6. 【转载】浅析依赖倒置(DIP)、控制反转(IOC)和依赖注入(DI)

    原文地址 http://blog.csdn.net/briblue/article/details/75093382 写这篇文章的原因是这两天在编写关于 Dagger2 主题的博文时,花了大量的精力来 ...

  7. 控制反转IOC与依赖注入DI - 理论篇

    学无止境,精益求精 十年河东十年河西,莫欺少年穷 昨天是五一小长假归来上班的第一天,身体疲劳,毫无工作热情.于是就看看新闻,喝喝茶,荒废了一天 也就在昨天,康美同事张晶童鞋让我学习下IOC的理论及实现 ...

  8. 依赖倒置(DIP)、控制反转(IOC)和依赖注入(DI)

    原文: https://blog.csdn.net/briblue/article/details/75093382 写这篇文章的原因是这两天在编写关于 Dagger2 主题的博文时,花了大量的精力来 ...

  9. 20181123_控制反转(IOC)和依赖注入(DI)

    一.   控制反转和依赖注入: 控制反转的前提, 是依赖倒置原则, 系统架构时,高层模块不应该依赖于低层模块,二者通过抽象来依赖 (依赖抽象,而不是细节) 如果要想做到控制反转(IOC), 就必须要使 ...

  10. Spring框架学习笔记(1)——控制反转IOC与依赖注入DI

    Spring框架的主要作用,就是提供了一个容器,使用该容器就可以创建并管理对象.比如说Dao类等,又或者是具有多依赖关系的类(Student类中包含有Teacher类的成员变量) Spring有两个核 ...

随机推荐

  1. java CopyOnWriteArrayList的使用

    除了加锁外,其实还有一种方式可以防止并发修改异常,这就是将读写分离技术(不是数据库上的). 先回顾一下一个常识: 1.JAVA中“=”操作只是将引用和某个对象关联,假如同时有一个线程将引用指向另外一个 ...

  2. POJ -- 3842

    An Industrial Spy   Description Industrial spying is very common for modern research labs. I am such ...

  3. [Tommas] UNION 和 UNION ALL 的区别

    UNION指令的目的是将两个 SQL 语句的结果合并起来.从这个角度来看,UNION跟 JOIN 有些许类似,因为这两个指令都可以由多个表格中撷取资料.UNION的一个限制是两个 SQL 语句所产生的 ...

  4. 使用正则表达式匹配JS函数代码

    使用正则表达式匹配JS函数代码 String someFunction="init"; Pattern regex = Pattern.compile("function ...

  5. ios中的容器类 ViewController

    https://developer.apple.com/library/ios/featuredarticles/ViewControllerPGforiPhoneOS/AboutViewContro ...

  6. 《算法:C语言实现》阅读笔记

    //从今天起准备认真看完这本书.本渣虽然笨,但是窝懒啊.... //今天开始看第一章.希望坚持下去. 第一章 引言 通过讨论连通问题的几种算法,来引出算法的重要性. 1.1 连通问题的快速查找算法 感 ...

  7. 计算json的和

      var count=0;    for(var i=0;i<data.length;i++){        count+=data[i].data;   }

  8. IOS GCD 使用 (二)

     上一节,主要介绍了GCD的基本的概念,这节将用代码深入详细介绍GCD的使用. 一  使用介绍    GCD的使用主要分为三步:创建代码块;选择或创建合适的分发队列;(同步.异步方式)向分发队列提交任 ...

  9. JBPM学习(二):ProcessEngine与Service API

    1.获取processEngine的方法: a) 方法一 private ProcessEngine processEngine = new Configuration().setResource(& ...

  10. chrome浏览器当表单自动填充时,怎么去除浏览器自动添加的默认样式。

    参考blog来自 http://segmentfault.com/q/1010000000671971 chrome浏览器当表单自动填充时,怎么去除浏览器自动添加的默认样式. 一.发现该问题的原因-是 ...