在討論.Net的依賴注入(DI)之前,我們需要知道我們為什麼需要使用依賴注入
依賴反轉原理(DIP):
DIP允許您將兩個類解耦,否則它們會緊密耦合,這有助於提高可重用性和更好的可維護性
DIP介紹:
- 高階模組不應依賴於低階模組。兩者都應依賴抽象。
- 抽象不應依賴細節。細節應取決於抽象。
下面我們通過一個示例來探討前者
class Foo {
Foo(Car _car){
//dosomething
}
}
在上面的程式碼中,類Foo直接依賴於Car,當這兩個類嚴重依賴時會導致兩個問題
- Foo不能用不同的樣式例項化car,即如果有新的汽車型別,例如:Audi來了,Foo則不能重複使用
- 每次修改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中使用,而無需複雜的配置。
服務註冊的三種型別:
- Transient:需要時建立新例項
- Scoped:可以為每個新作用域建立一個新例項
- Singleton:第一個請求上建立一個新例項,並且在應用程式的剩餘生命週期中,將相同的例項提供給所有使用者類。
推薦做法:
- 範圍服務通常應由單個Web請求/執行緒使用。因此,不應該線上程之間共享服務範圍。
- 配置為單例的服務可能會導致應用程式中的記憶體洩漏。
- 記憶體洩漏通常是由單例服務引起的。這是因為建立的例項不會被丟棄,它將保留在記憶體中直到應用程式結束。因此,一旦不使用它們,最好將它們釋放。
- 將服務註冊為臨時服務會縮短其使用壽命,通常可能不太在乎多執行緒和記憶體洩漏。
- 不要在單例服務中依賴瞬態或作用域服務。因為瞬時服務在單例服務注入時成為一個單例例項,並且如果瞬態服務不旨在支援這種情況,則可能導致問題。在這種情況下,ASP.NET Core的預設DI容器已經引發異常。
依賴項注入技術使您可以進一步改進它。它提供了一種將物件的建立與使用分開的方法。這樣,您可以在不更改任何程式碼的情況下替換依賴關係,這還可以減少業務邏輯中的程式碼。
如有哪裡講得不是很明白或是有錯誤,歡迎指正
如您喜歡的話不妨點個贊收藏一下吧