IoC的基本概念
IoC(Inversion of Control),意為“控制反轉”,也叫依賴注入(Dependency Injection),也有人認為依賴注入是控制反轉的一種方式。IoC的本質是引入代理者以減少依賴關系。下面通過引入實例以比較IoC的好處
假設存在一個普通的業務場景,獲取服務提供者發送的消息並加以處理
以下是上功能實現的類文件
```
public class OurInfoProvider
{
private IOurInfoListener infoListener;
private IOurPersister infoPersister;
public void getAndPersisterInfo()
{
}
}
```
依賴類需要初始化,這是最直接的處理方式,我們主動的創建相關類實例,在OurInfoProvider類中形成了對aInfoListener、aInfoPersister的直接依賴
```
public OurInfoProvider
{
infoListener = new AInfoListener();
infoPersister = new AInfoPersister();
}
```
但是對於OurInfoProvider的業務處理過程,其並不關心依賴對象的實例化過程,只需要訂閱或引入它們的實例即可,相關的實例化過程並不應該由OurInfoProvider來實現,對於OurInfoProvider而言,這不是它的職責范圍內
基於以上共識,OurInfoProvider只需要引入依賴對象的實例。而依賴對象的實例化過程無法忽略,由其他對象負責;同時OurInfoProvider的引用依賴對象需要來自於一個容器,這就是IoC
依賴注入的方式,構造方法注入、setter方法注入、接口注入,其中接口注入的方式由於侵入性已較少使用;構造方法注入,對象初始化后即可使用,但是構造方法無法被繼承、無法設置默認值;而setter方法注入的特點與構造方法相對
構造方法注入:
```
public OurInfoProvider(IOurInfoListener infoListener, IOurInfoPersister infoPersister)
{
this.infoListener = infoListener;
this.infoPersister = infoPersister;
}
```
常常會看到IoC的好處是解耦,但是卻不理解這在實際上到底由什么好,下面舉例說明
假如增加一個BInfo的信息源以提供OurInfoProvider處理,當我們以直接創建依賴對象時,在OurInfoProvider內確定了接口的實現對象,不能復用以滿足BInfo的對象。但是假如我們以構造方法注入,構造方法參數確定接口的實現對象即可。本質上是對初始化的控制權的轉移,使得OurInfoProvider不負責可變之處,保持通用性即可
```
OurInfoProvider aOurInfoProvider = new OurInfoProvider(new AInfoListener(), new AInfoPersister());
OurInfoProvider bOurInfoProvider = new OurInfoProvider(new BInfoListener(), new BInfoPersister());
```
通過構造方法注入使得OurInfoProvider不必修改構造方法
IoC使得OurInfoProvider不關心引入依賴對象的初始化過程,也就是其初始化過程對OurInfoProvider是非侵入式、分離的,可以添加鈎子等各種處理過程,而OurInfoProvider無感知。例如對引入依賴對象的Mock,但不影響OurInfoProvider的任何邏輯,而這也正符合IoC的意義