IoC,是面向对象编程中一种设计原则,可以用来减低计算机代码之间的耦合度
- 其中最常见的方式叫做依赖注入(Dependency Injection,简称DI)
- 还有一种方式叫“依赖查找”(Dependency Lookup)
通过控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体将其所依赖的对象的引用传递给它。也可以说,依赖被注入到对象中。
按照以上思想设计的框架都叫IoC,它只是一类框架的总称
- 例如C#的IoC框架:MEF、Autofac、Castle Windsor、Unity
术语
DI,Dependency Injection依赖注入
IoC,Inversion of Control控制反转
名词 | 说明 |
---|---|
IoC容器 | 就是一个工厂,它负责创建对象的 |
IoC控制反转 | 只是把上端对下端的依赖,换成第三方容器决定 |
DI依赖注入 | 在构造某个对象时,能将对象依赖的东西自动的初始化进去 正是因为要实现IOC,所以才诞生了DI的技术手段 |
DIP | 上层模块不应该依赖底层模块,它们都应该依赖于抽象,具体点是Service不应该依赖于Repository,而应该依赖于IRepository |
DI的优点:
- 解耦,没有强依赖。模块只会依赖接口,接口是具体类的抽象,所以它们只依赖了抽象
- 解耦了就利于单元测试
- 不需要了解具体的服务类
- 不需要管理服务类的生命周期
解释
以下解释为了简化,可能不是很贴切。但若有原则性问题,欢迎指出。
某个代码框架当中,我们定义了一个抽象工厂,这个工厂管理了一大堆对象。
但是一般在最顶层的时候(Main函数所在模块),我们需要告诉工厂,它要管理哪些类,比如抽象工厂.AddClass(帽子)
interface I帽子{
String Name;
String Id;
}
class 帽子 : I帽子;
Main() {
抽象工厂.AddClass(帽子)
}
在某个子模块当中,如果需要用到帽子,可以这样定义
class A{
public A(I帽子 x) {
x.Name;
}
}
当程序跑起来的时候,工厂发现:“我创建A对象,需要一个I帽子
,而I帽子
可以由帽子
提供”。于是工厂就创建了一个帽子
,并通过构造函数,丢给了A
,也创建了A
以上内容对应到具体依赖注入的术语是:
- 工厂创建了
帽子
,并把帽子
丢给了A
,这个动作就叫控制反转(IoC)。帽子
是由工厂创建,控制权原来在工厂,现在工厂把控制权丢给了A,即表示控制权反转给了A。 - 把
帽子
给A
这个动作,也叫依赖注入。此模块并没有直接依赖帽子
,而是依赖的I帽子
,真正的依赖,是最顶级模块(Main模块)注入进来的 - 这个抽象工厂就叫IoC容器,里面保存了一大堆可以控制反转的元素
- 而工厂里管理的这些类,一般称为Service(服务)
- 其他类型(
A
)在用到这些类(帽子
)的时候,就可以请求实例
但是这个帽子
也有生命周期:是每创建一个A,就创建一个帽子(Transient);还是说不管创建几个A,帽子都是同一个(Singleton)。
也就是注册服务的时候,可以指定这些实例的生命周期
- Transient:每次被请求的时候都会重新创建一次
- Scoped:
- Singleton:系统中就只有一个