軟體工程中,依賴注入(dependency injection,縮寫為 DI)是一種軟體設計模式,也是實現控制反轉的其中一種技術。這種模式能讓一個物件接收它所依賴的其他物件。「依賴」是指接收方所需的對象。「注入」是指將「依賴」傳遞給接收方的過程。在「注入」之後,接收方才會呼叫該「依賴」[1]。此模式確保了任何想要使用給定服務的物件不需要知道如何建立這些服務。取而代之的是,連接收方物件(像是 client)也不知道它存在的外部代碼(注入器)提供接收方所需的服務。

註:程式語言層次下,「接收方」為對象和 class,「依賴」為變數。在提供服務的角度下,「接收方」為客戶端,「依賴」為服務。

該設計的目的是為了分離關注點,分離接收方和依賴,從而提供鬆耦合以及代碼重用性

傳統編程方式,客戶對象自己建立一個服務實例並使用它。這帶來的缺點和問題是:

  • 如果使用不同類型的服務對象,就需要修改、重新編譯客戶類。
  • 客戶類需要通過組態來適配服務類及服務類的依賴。如果程式有多個類都使用同一個服務類,這些組態就會變得複雜並分散在程式各處。
  • 難以單元測試。本來需要使用服務類的 mock 或 stub,在這種方式下不太可行。

依賴注入可以解決上述問題:

  • 使用介面或抽象基礎類別,來抽象化依賴實現。
  • 依賴在一個服務容器中註冊。客戶類建構函式被注入服務實例。框架負責建立依賴實例並在沒有使用者時銷毀它。

概念

編輯

依賴注入涉及四個概念:

  • 服務:任何類,提供了有用功能。
  • 客戶:使用服務的類。
  • 介面:客戶不應該知道服務實現的細節,只需要知道服務的名稱和 API。
  • 注入器:Injector,也稱 assembler、container、provider 或 factory。負責把服務引入給客戶。

依賴注入把對象構建與對象注入分開。因此建立對象的 new 關鍵字也可消失了。

實現方式

編輯
  • 建構子注入:依賴由客戶對象的建構函式傳入。
  • Setter 注入:客戶對象暴露一個能接收依賴的 setter 方法。
  • 介面注入:依賴的介面提供一個注入器方法,該方法會把依賴注入到任意一個傳給它的客戶。客戶實現一個setter介面,可設定依賴。

參考資料

編輯
  1. ^ James Shore: Dependency Injection Demystified. www.jamesshore.com. [2020-02-06]. (原始內容存檔於2020-06-30).