.Net核心依賴項注入:生命周期和最佳實踐


在這里插入圖片描述
在討論.Net的依賴注入(DI)之前,我們需要知道我們為什么需要使用依賴注入
依賴反轉原理(DIP):
DIP允許您將兩個類解耦,否則它們會緊密耦合,這有助於提高可重用性和更好的可維護性
DIP介紹:

  1. 高級模塊不應依賴於低級模塊。兩者都應依賴抽象。
  2. 抽象不應依賴細節。細節應取決於抽象。

下面我們通過一個示例來探討前者

class Foo {
  Foo(Car _car){
    //dosomething
  }
}

在上面的代碼中,類Foo直接依賴於Car,當這兩個類嚴重依賴時會導致兩個問題

  1. Foo不能用不同的樣式實例化car,即如果有新的汽車類型,例如:Audi來了,Foo則不能重復使用
  2. 每次修改Car類都會直接影響Foo類

為了避免這兩個問題,DIP建議較高級別的模塊Foo不應直接依賴於較低級別的模塊,Car而應兩者都依賴於抽象,例如:接口

class Foo {
  Foo(ICar _car){
    // something
  }
}
class Car : ICar {
  
}
class Sedan : ICar{
}

只需引入一個簡單的抽象ICar,Foo它就可以兼容所有遵循契約或抽象的類ICar。
我們現在如何將當前方法使用依賴注入?
如果您需要修改較低級別的類,DIP可以提高代碼的可重用性並限制波動效果。即使完美地實現了DIP,該接口也僅在較高級別的類中解耦了較低級別的類的用法,而不是其實例化。在代碼的某些地方,您需要實例化接口的實現。這樣可以防止您用另一種動態替換接口的實現。

依賴注入在這里發揮了作用,有助於從實例中區分使用實例。簡而言之,只要DI框架在類中看到任何已注冊服務的依賴項,它就會提供具體的實例化。

假設ICar已在DI框架中注冊以提供的實例Car,則的構造函數將Foo始終Car為每個Foo對象實例接收一個實例

.NET中的DI:

在.NetCore框架之前,我們更多的是使用第三方DI框架,例如Autofac。但是,當.NetCore出現后。“Startup”類提供了一種稱為的方法configureServices供我們將服務注冊到容器內。

public class Startup
 {
    public void ConfigureServices(IServiceCollection services) {
    //服務注入
    services.AddTransient<ICar, Car>();
  }
}

因此,對於每個請求,將使用容器中解析的所有依賴項來獲取實例。所有這些都可以在.Net core中使用,而無需復雜的配置。

服務注冊的三種類型:

  1. Transient:需要時創建新實例
  2. Scoped:可以為每個新作用域創建一個新實例
  3. Singleton:第一個請求上創建一個新實例,並且在應用程序的剩余生命周期中,將相同的實例提供給所有使用者類。

推薦做法:

  1. 范圍服務通常應由單個Web請求/線程使用。因此,不應該在線程之間共享服務范圍。
  2. 配置為單例的服務可能會導致應用程序中的內存泄漏。
  3. 內存泄漏通常是由單例服務引起的。這是因為創建的實例不會被丟棄,它將保留在內存中直到應用程序結束。因此,一旦不使用它們,最好將它們釋放。
  4. 將服務注冊為臨時服務會縮短其使用壽命,通常可能不太在乎多線程和內存泄漏。
  5. 不要在單例服務中依賴瞬態或作用域服務。因為瞬時服務在單例服務注入時成為一個單例實例,並且如果瞬態服務不旨在支持這種情況,則可能導致問題。在這種情況下,ASP.NET Core的默認DI容器已經引發異常。

依賴項注入技術使您可以進一步改進它。它提供了一種將對象的創建與使用分開的方法。這樣,您可以在不更改任何代碼的情況下替換依賴關系,這還可以減少業務邏輯中的代碼。

如有哪里講得不是很明白或是有錯誤,歡迎指正
如您喜歡的話不妨點個贊收藏一下吧


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM