原文
http://www.cnblogs.com/forcertain/archive/2011/07/09/2101717.html
http://www.cnblogs.com/yycilpppp/archive/2007/01/08/615011.html
--------------------------------------------------------
IOC:控制反转,是一种设计模式。一层含义是控制权的转移:由传统的在程序中控制依赖转移到由容器来控制;第二层是依赖注入:将相互依赖的对象分离,在spring配置文件中描述他们的依赖关系。他们的依赖关系只在使用的时候才建立。简单来说就是不需要NEW一个对象了。
IOC,翻译来就是控制反转,其实理解成为控制转移才更贴近实际,也就是控制权的转移。例如我们.net的开发网站用到的web form框架,从用户请求网页开始,控件权在框架手中,但是本身框架提供很多供我们开发的接口、扩展,例如我们在Page_Load中写了一些代码,这其中就有IOC的概念,执行到Page_Load时,控制权就从框架转移到了我们代码里,我们的代码就可以控制整个的或者部分的执行了,执行完毕之后,再次返还给框架,框架再去负责运行其它的要运行的东西。为什么Castle Windsor/spring等等符合IOC的理念,它们主要解决什么问题呢?因为他们转移一些控制权到自己手里,它们接管了对象的创建、销毁等的控制权。他们是为了解决项目中组件的相互依赖问题的,他们要达到的目的就是可以在运行中替换组件,也就是所说的以插件的方式运行。所说来就是我们只负责编写负责各个职责的模块,而各个模块的依赖关系则交给我们的IOC容器去实现或者按照我们的配置由IOC去实现了。
依赖注入的目的是要尽量消除对象之间的依赖性,减少对象的耦合程度。但是为什么我们要消除这些依赖呢?假如我们有这样一个场景:编写一个程序需要记录运行日志,我们也许会这样写:
//主程序
class Program
{
static void Main(string[] args)
{
Console.Write("Please Input Some Words:");
string inputData = Console.ReadLine();
ILogger logger=new LoggerA();
Logger.write(inputData);
}
}
//记录类接口
Public interface ILogger
{
Public void wirtelog(string message)
}
//记录类的一个实现
Class LoggerA:ILogger
{
Public void writelog(string message)
{
……..
}
}
由于program类使用了“ ILogger logger=new LoggerA()”来获取LoggerA的实例却使得Program类既依赖于ILogger接口也依赖于LoggerA类。我们设计的目的当然是希望Program类只依赖于ILogger接口了,但是我们如何获取实现了ILogger接口的实例(如LoggerA)呢?
在现实中这种情况还有一个名称叫:插件。我们希望Program类能够与任何事项实现了ILogger接口的类配合工作,并且允许在运行期插入具体的实现类,插入行为完全脱离Program编写者的控制,不需要重新编译Prorgram,现在的问题就集中在如何设计这个连接过程,然Program在不知道ILogger的具体实现的情况下与其协同工作。而解决这个问题的方法就可以使用IOC(控制反转),使用一个 IOC框架类来管理对象的配置、生成、释放等,程序只与IOC类进行交互来获取对象。
4.依赖注入的实现方式
目前依赖注入的实现方式主要有3中:构造注入、设值注入和接口注入。
种种方法都是为了降低对象之间的依赖性,但并不能消除对象之间的依赖,只是将这种依赖降到最小或者推迟依赖发生的时间(编译前依赖还是编译后依赖(插件)),甚至将其依赖性用配置文件分离出来。
为了说明几种注入方式的区别,我们假设有一个类A,还有一个类B,类B是实现IB这个接口的:
构造子注入:在类A的构造函数里出入一个参数,就是类B的实例。
设置注入:类A有一个只写属性,就是类B
接口注入:类A接受一个IB接口的参数。