前言

終於寫到DI了,這應該是一開始學習三層式架構後的第二座高山,直到今天我也還不敢稱自己完全懂,頂多只能說是會用,剛好藉著這次機會複習概念。

本文

講解 DI 前會有兩個先行觀念需要了解,分別是:

  • 1、DIP(Dependency Inversion Principle) 依賴反轉。
  • 2、IOC(Inversion of Control) 控制反轉。

1、DIP 依賴反轉。

複習一下前面講解到的依賴反轉概念:

我們了解到 DIP 最重要的目標是要解除物件與物間之間直接依賴的關係。
不熟的同學起點這複習

2、IOC 控制反轉。

那甚麼又是控制反轉呢?

控制反轉最重要的概念是:

把對於某個物件的控制權移轉給第三方容器。

甚麼意思呢?

回憶一下,還記得前面實作的第一版API嗎?

我們的 Controller 在跟 Repository 要資料的時候是怎麼做的呢?

看到關鍵字了嗎?

沒有?那這樣呢?

就是那個 NEW 代表著我們的 Controller 其實是直接依賴 Repository 的。
他們之間的關係如下圖。

所以理想中 IOC 概念我們的關係圖應該長這樣:

我們的 Controller 應該把對於 Repository 的控制權移交給 IOC。

3、DI 依賴注入。

講了這麼多那所以甚麼是 DI 呢?

聰明的同學應該發現了上述的 DIP、IOC 都只是一種精神、概念;而 DI 就是實現上述兩種精神的方法。

講解 DI 的精神最經典的就是:

好萊塢原則 (Hollywood Principle)
don‘t call us, we‘ll call you
在好萊塢演員要應徵的時候僅需要把履歷上繳,之後剩下的就只能等待演藝公司通知。
這就是一種被動接受的方式。

所以呢有了 DI 的概念我們理想中的關係圖應該要變成:

4、注入的方式。

注入的方式有以下三種:

  • a、建構式注入 (Constructor Injection)
  • b、設值方法注入 (Setter Injection)
  • c、介面注入 (Interface Injection)

以我們先前的 Controller 進行示範

    public class ProductContorller : ControllerBase
    {
        
        //a、建構式注入
        private readonly IProductRepository _productRepository;
        
        public ProductContorller(
        IProductRepository productRepository)
        {
            this._productRepository = productRepository;
        }
        
        //b、設值方法注入 
        public ProductContorller() 
        {
        } 
        public IProductRepository _productRepository { get; set; }

        // c、介面注入
        public ProductContorller() 
        {
        }

        public IEnumerable<ProductModel> GetProductList(
         IProductRepository _productRepository) {
           ...
         } 
    
    }

後記

工作上最常用到的注入方式還是建構式注入,另外兩種較為陌生,若是用法有誤還請多多指教;這邊前置作業都講解完,下一篇就可以進入API第二階段了!

參考連結