啥叫依賴注入?
我們在代碼實現中經常手動創建對象。
但是 這樣存在問題,首先代碼修改維護的難度大,其次,代碼耦合性太大,依賴關係混亂。
我們可以使用依賴注入的方法代替:
接口實現替換可以自由切換。
依賴注入的註冊方式
services.AddScoped<Interface, Implement>();
services.AddSingleton<Implement>();
services.AddTransient<Interface,Implement>();
三種依賴注入的註冊方式
Scoped是一種線程獨立的對象
Singleton就是單例模式
Transient每次調用都會有新的創建。
也可以註冊自己創建的對象:
對於依賴注入的管理,避免混亂,我們常常採用擴展方法進行定義:
多個實現類的註冊
多個實現類可以同時註冊:
我們的調用方法也可以使用IEnumrable<Interface>來注入:
我們這裏獲取的是不同的實現類的對象。
默認情況下,如果存在多個實現類的註冊,而接收參數只有一個,那麼最後註冊到容器的類型實例是被註冊的類。
依賴注入的途徑
我們剛剛使用的都是構造函數進行注入。還可以通過Action方法進行注入,View Template也可以注入。
用戶的請求,每次基本上就只訪問一個方法,如果從構造器注入的實例過多,那麼,每次訪問的時候,不管用沒用到,都會創建相應的實例注入到控制器中。因此,這是一種浪費和性能損耗。
上面這段代碼,使用[FromServices]特性對兩個接口的示例進行標註,說明,這個參數是需要容器注入進來的,而不是用戶的請求參數。
那麼,怎麼掌握好這個度呢?
如果,某個實例是某個方法所獨享的,我們建議使用Action注入。如果超過兩個以上的方法都使用的實例,我們建議使用構造器注入。
模板引擎的注入
使用@inject進行注入,一般用不到。
不同的服務的注入週期
Transient:每次都會有新的對象。
Scoped:每個請求內是同一個實例。
Singleton:每次都是相同的實例。
選擇哪種生命週期進行注入呢?
一般看實例的狀態。什麼是狀態呢?說白了就是成員變量。成員變量存儲着狀態。
每次都是新的。那麼,針對每次,你獲取到的都是具有特色的實例,不一樣的實例。
單個請求內是一樣的,這種對於數據庫連接,鑑權服務等等都是可以的。
對於單例模式,不需要更改。比如,工具類,輸入參數,輸出值。不維護狀態。必須是線程安全的。