依賴注入(Dependency Injection:DI):
程序運行過程中,如果需要調用另一個對象協助時,無須在代碼中創建被調用者,而是依賴於外部的注入。
通俗來講,就是把有依賴關系的類放到容器中,然后在我們需要這些類時,容器自動解析出這些類的實例。
依賴注入最大的好處時實現類的解耦,利於程序拓展、單元測試、自動化模擬測試等。
控制反轉(Inversion of Control:IOC):
控制反轉只是一個概念,也就是將創建對象實例的控制權(原本是程序員)從代碼控制權剝離到 IOC 容器
中控制。
IOC/DI的優缺點:
-
優點
- 依賴注入把對象的創造交給外部去管理,很好的解決了代碼緊耦合(tight couple)的問題,是一種讓代碼實現松耦合(loose couple)的機制
- 松耦合讓代碼更具靈活性,能更好地應對需求變動,以及方便單元測試
-
缺點
- 目前主流的
IOC/DI
基本采用反射的方式來實現依賴注入,在一定程度會影響性能
- 目前主流的
依賴注入的三種形式:
一 、構造方法注入
目前構造方法注入是依賴注入推薦使用方式。
-
優點
- 在構造方法中體現出對其他類的依賴,一眼就能看出這個類需要依賴哪些類才能工作
- 脫離了 IOC 框架,這個類仍然可以工作,POJO 的概念
- 一旦對象初始化成功了,這個對象的狀態肯定是正確的
-
缺點
- 構造函數會有很多參數(Bad smell)
- 有些類是需要默認構造函數的,比如 MVC 框架的 Controller 類,一旦使用構造函數注入,就無法使用默認構造函數
- 這個類里面的有些方法並不需要用到這些依賴(Bad smell)
代碼示例:
public class FurionService { private readonly IRepository _repository; public FurionService(IRepository repository) { _repository = repository; } }
二 、屬性方式注入
通過屬性方式注入容易和類的實例屬性混淆,不建議使用。
-
優點
- 在對象的整個生命周期內,可以隨時動態的改變依賴
- 非常靈活
-
缺點
- 對象在創建后,被設置依賴對象之前這段時間狀態是不對的
- 不直觀,無法清晰地表示哪些屬性是必須的
代碼示例:
public class FurionService { public IRepository Repository { get; set; } }
三 、方法參數注入
方法參數注入的意思是在創建對象后,通過自動調用某個方法來注入依賴。
-
優點:
- 比較靈活
-
缺點:
- 新加入依賴時會破壞原有的方法簽名,如果這個方法已經被其他很多模塊用到就很麻煩
- 與構造方法注入一樣,會有很多參數
代碼示例:
public class FurionService { public Person GetById([FromServices]IRepository repository, int id) { return repository.Find(id); } }