在討論.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容器已經引發異常。
依賴項注入技術使您可以進一步改進它。它提供了一種將對象的創建與使用分開的方法。這樣,您可以在不更改任何代碼的情況下替換依賴關系,這還可以減少業務邏輯中的代碼。
如有哪里講得不是很明白或是有錯誤,歡迎指正
如您喜歡的話不妨點個贊收藏一下吧