# [筆記] 依賴注入 DI、控制反轉 IoC、依賴反轉原則 DIP
>DI is about wiring, IoC is about direction, and DIP is about shape.
* 依賴注入 ( Dependency Injection ) : 為一種**設計模式**,將依賴通過注入的方式提供給需要的 class,是 IoC 與 DIP 的具體表現
* 控制反轉 ( Inversion of Control ) : 為一種**思想**,函式主要功能之外的其他功能應該由第三方完成
* 依賴反轉原則 ( Dependency-Inversion Principle ) : 為一種**思想**,較高層次的模組不應該依賴較低層次的被模組,應該提供接口讓較低層次的模組實現
* 目的都是為了**解偶**,使程式**好維護**,且更**容易測試**
### 依賴反轉原則
* 原則 :
* 高階模組不該依賴於低階模組,兩者都該依賴抽象
* 抽象不依賴具體實作方式,具體實作方式則依賴抽象
* 雖然透過依賴反轉原則可以改變依賴於抽象,但程式上還是必須 new 出 instance,就是呼叫者對依賴的控制流程有主導權
* 這樣若更換低階模組,還是必須是調整高階模組 `new XXX()`
* 這時就要使用到控制反轉
### 控制反轉
* 原則 :
* 把對於某個物件的控制權移轉給第三方容器
* 例如 :
* A 物件內部需要使用 B、C 物件,那 B、C 與 A 就有耦合,A 控制著 B、C
* 控制反轉是把 A 對 B、C 的控制權轉交第三方容器
* 降低 A 與 B、C 間的耦合,都依賴於第三方容器

* 原本的關係圖

* 使用控制反轉後的關係圖
* 與好萊塢法則一致 :
> Don’t call me, I’ll call you.
### 依賴注入
* 為實現依賴反轉原則與控制反轉的其中一種設計模式
* 把被依賴物件注入被動接收物件中
---
* `小明` 是個喜歡叫麥當勞的人,所以他每天都會打給 `他家附近的麥當勞` 叫麥當勞來吃
* 若是有天 `他家附近的麥當勞` 公休了,那小明就要另外再找麥當勞,由此可知小明耦合`他家附近的麥當勞`
* 如果今天 `小明` 是把他的要求給 `外送公司`,那麼 `外送公司` 就會幫他尋找有沒有營業中的麥當勞,若是 `他家附近的麥當勞` 公休了,`外送公司` 就會自動找另一間營業中的麥當勞
* 原本 `小明` 需耦合於 `他家附近的麥當勞`,現在被 `外送公司` 做了控制反轉,由 `外送公司` 來提供麥當勞
* `小明` 不用管 `他家附近的麥當勞` 是否公休,`外送公司` 會幫他找到營業中的麥當勞
* `小明` 可看作被動接收物件
* `他家附近的麥當勞` 可看作被依賴物件
* `外送公司` 可看作 IoC 容器
#### 程式碼
* `小明` 自己依賴於 `他家附近的麥當勞`
```csharp=
public class Mine
{
public Mcdonald mcdonald = new Mcdonald();
public void Eat()
{
mcdonald.Service();
}
}
```
* 呼叫使用時
```csharp=
Mine mine = new Mine();
mine.Eat();
```
* `小明` 找 `外送公司`
```csharp=
private static IContainer MiddleCompany()
{
ContainerBuilder builder = new ContainerBuilder();
//在外送公司裡寫需求申請單
builder.RegisterType<MineWithMiddle>();
//小明所需麥當勞需求
builder.RegisterType<Mcdonald>().As<IService>();
return builder.Build();
}
```
* 呼叫使用時
```csharp=
IContainer middleCompany = MiddleCompany();
//外送公司自動幫小明注入一個營業中的麥當勞
MineWithMiddle mineWithMiddle = middleCompany.Resolve<MineWithMiddle>();
mineWithMiddle.Eat();
```
### 参考
* [DIP IOC DI 基本概念](https://dotblogs.com.tw/lesterhsu0022/2017/12/28/182707)
* [IOC(控制反轉) , DI(依賴注入) 深入淺出~~](https://dotblogs.com.tw/daniel/2018/01/17/140435)
###### tags: `筆記` `依賴注入 DI` `控制反轉 IoC` `依賴反轉原則 DIP`