ASP.NET Core 支援相依性插入 (DI) 軟體設計模式,這是用來在類別與其相依性之間達成控制權反轉 的技術。
相依性插入概觀
假設我們有以下服務
一般寫法通常在要使用時實作
但這樣就有以下問題
- 若要將
MyDependency
取代為不同的實作,必須修改IndexModel
類別。
- 若
MyDependency
有相依性,那些相依性必須同時由IndexModel
類別設定。 在具有多個相依於MyDependency
之多個類別的大型專案中,設定程式碼在不同的應用程式之間會變得鬆散。
相依性插入可透過下列方式解決這些問題:
- 使用介面或基底類別來將相依性資訊抽象化。
- 在服務容器中註冊相依性。 ASP.NET Core 提供內建服務容器 IServiceProvider。 服務通常會在應用程式的
Program.cs
檔案中註冊。
- 將服務「插入」到服務使用位置之類別的建構函式。 架構會負責建立相依性的執行個體,並在不再需要時將它捨棄。
插入方法 (AddSingleton
、AddScoped
、 AddTransient
) 詳細比較
特性 | AddSingleton | AddScoped | AddTransient |
生命週期 | 整個應用程式生命週期中只創建一個實例 | 每個作用域中(通常對應於一次 HTTP 請求)只創建一個實例,並在整個作用域中共用 | 每次注入時都創建一個新的實例 |
應用場景 | - 資料庫連線
- 全域性的共用資源
- 共享資料
- 共享設定 | - Entity Framework Core 的 DbContext
- 需要在特定作用域中共用的服務 | - 輕量、無狀態的服務
- 不需要在不同地方共用實例的服務 |
使用建議 | 小心使用,可能導致全域狀態和潛在競爭條件 | 適用於需要在一個特定作用域中共用的服務 | 適用於每次請求都需要一個新實例的情況 |
多執行緒安全性 | 可能存在潛在的競爭條件,請謹慎使用 | 在每個作用域內創建不同的實例,通常較為安全 | 在多執行緒環境下較為安全,每次都有新實例 |
資源使用 | 需要較多的記憶體,因為實例在整個應用程式生命週期中都存在 | 較節省記憶體,因為實例在特定作用域內被共用 | 較節省記憶體,因為實例只在需要時創建並在短時間內被釋放 |