| 術語 | 全稱 | 定位 | 關係 |
|---|---|---|---|
| DIP | Dependency Inversion Principle | 軟體架構設計**原則** (抽象層面) | 源頭思想 |
| IoC | Inversion of Control | 軟體設計**模式** (反轉流程/依賴/介面) | DIP 的具體實現方式 |
| DI | Dependency Injection | IoC 的一種**實現技術** (注入依賴) | IoC 的主流落地手段 |
| IoC Container | IoC 容器 | DI 的**框架** (映射依賴、管理生命週期、建構物件) | DI 的自動化工具 |
ATM (高層模組) 定義插卡介面 (卡槽、晶片讀取協定)。
銀行卡 (低層模組) 實作該介面 (晶片、磁條)。
使用者 (第三方/容器) 決定插入哪張卡。
→ 高層不依賴低層具體實作,雙方依賴抽象介面。這就是 DIP。
public class SqlServerDal { public void Add() { Console.WriteLine("SQL Server 寫入訂單"); } }
public class Order {
private readonly SqlServerDal _dal = new SqlServerDal(); // 直接 new,死綁定
public void Add() => _dal.Add();
}
換資料庫必須修改 Order 類別,違反開放封閉原則 (OCP)。
public interface IDataAccess { void Add(); }
public class SqlServerDal : IDataAccess { public void Add() => Console.WriteLine("SQL Server 寫入"); }
public class AccessDal : IDataAccess { public void Add() => Console.WriteLine("Access 寫入"); }
public class Order {
private readonly IDataAccess _dal;
public Order(IDataAccess dal) => _dal = dal; // 建構函式注入
public void Add() => _dal.Add();
}
| 方式 | 代碼 | 特點 |
|---|---|---|
| 建構函式注入 | var order = new Order(new AccessDal()); | 不可變依賴、強制完整性、最推薦 |
| 屬性注入 | order.Ida = new AccessDal(); | 可選依賴、循環依賴時有用、需注意 null |
| 介面注入 | order.SetDependence(new AccessDal()); | 較少用、需額外介面、複雜度高 |
var kernel = new StandardKernel();
kernel.Bind<IDataAccess>().To<SqlServerDal>(); // 映射關係
var order = kernel.Get<Order>(); // 容器自動建構 Order 並注入 SqlServerDal
order.Add();
容器職責:掃描映射 → 建構物件圖 → 注入依賴 → 管理生命週期 (Singleton/Transient/Scoped)。
DIP 是「為什麼」,IoC 是「怎麼做」,DI 是「具體手段」,IoC Container 是「自動化工具」。
掌握這層遞進關係,並熟練至少一款 IoC 容器,是寫出可維護、可測試、可擴展軟體架構的關鍵基石。