对IOC和DI的理解

分类: asp.net技巧   出处:iocblog整理  更新时间:2008-06-06   添加到收藏  

  首先说一下什么是ioc和di,ioc是inversion of control(控制反转)的简写,di是dependency injection(依赖注入)的简写,martinfowler对ioc的解释为:“inversion of control is a common characteristic of frameworks, so saying that these lightweight containers are special because they use inversion of control is like saying my car is special because it has wheels.”

  我想对这一概念进行一个个人的阐述,以方便我的理解。控制反转,从字面意思来看,就是控制权由被动变主动又变为被动,或被动变主动又变为被动。从这个角度来说,ioc就变得非常容易理解了。

  举个例子:你的主管要求你做一件事情,这个时候就存在这么几个过程,

  主管命令你做事情(这个时候主动权在主管,你是被动的)

  你接到命令做事情(这个时候主题是你,你是主动的,控制权在你手里)

  你完成事情(这个时候主题依然是你,控制权在你手里)

  报告主管做完事情(主动权又叫交到主管手里了)

  上面的整个过程就完成了一次ioc,从上面可以看出,ioc的基本思想是控制权的转换过程。

  举个代码的例子:

  假如有class a,class b,在a内部会初始化一个b,调用b的一个方法domethod

  public class b

  {

  public void domethod()

  {[来源www.iocblog.net]

  /// do somthing;

  }

  }

  public class a

  {

  public void excute()

  {

  b b = new b();

  b.domethod();

  }

  }

  假如在main函数中如下执行:

  a a = new a();

  a.excute();

  从这两行代码来看,事实上也存在一个ioc的过程,a――>b――>a,理解的关键点就在在a的内部调用excute的时候,方法b.domethod的执行。

  理解了ioc,我们再看一下di,从上面a调用b我们可以看出,在初始化一个a的实例时,也必须实例化一个b,也就是说如果没有b或者b出了问题,a就无法实例化,这就产生了一种依赖,就是a依赖b,这种依赖从设计的角度来说就是耦合,显然它是无法满足高内聚低耦合的要求的。这个时候就需要解耦,当然解耦有很多种方法,而di就是其中一种。不管任何一种解耦方法,都不是说使a和b完全没有关系,而是把这种关系的实现变得隐晦,不那么直接,但是又很容易实现,而且易于扩展,不像上面的代码那样,直接new一个b出来。那为什么我们总是把ioc和di联系到一起呢?是因为di的基本思想就是ioc,而体现ioc 思想的方法还有另外一个,那就是service locator,这个方法好像涉及到的很少。

  di,依赖注入,从字面意思就可以看出,依赖是通过外接注入的方式来实现的。这就实现了解耦,而di的方式通常有三种,

  构造器注入

  属性设置器注入

  接口注入(我感觉接口注入是同时存在于上两种注入方式的,而不应该独立出来)

  以上的阐述只是为了先让我们能对ioc和di有一个感性的理解,那么ioc他真正解决的问题是什么呢?我们讲了那么多主动被动的问题,那我们是从什么视角来看待这个问题的呢?所谓为什么你是主动,而我不是主动呢?这就需要一个参照物,那这个参照物是什么呢?就是容器,在容器中来体现主动和被动。“用白话来讲,就是由容器控制程序之间的关系,而非传统实现中,由程序代码直接操控。这也就是所谓”控制反转“的概念所在:控制权由应用代码中转到了外部容器,控制权的转移,是所谓反转",这是通常对ioc的一个解释。从容器的角度来看主动和被动,和由容器来控制程序之间的关系,应该是相通的,是一个意思。到这里我们就应该基本明白了,ioc要解决的就是程序之间调用的一个问题,它应该是一个思想层面的东西,是一个中心,就像一支乐队的指挥,而程序就是乐器,通过指挥来协调各种乐器,来演奏出美好的音乐来。


Tag: IOC ,DI