.NetCore中三種注入方式的思考

邵佳楠發表於2019-07-05

該篇內容由個人部落格點選跳轉同步更新!轉載請註明出處!

.NetCore徹底詮釋了“萬物皆可注入”這句話的含義,在.NetCore中到處可見注入的使用。因此core中也提供了三種注入方式的使用,分別是:

  1. AddTransient:每次請求,都獲取一個新的例項。即使同一個請求獲取多次也會是不同的例項
  1. AddScoped:每次請求,都獲取一個新的例項。同一個請求獲取多次會得到相同的例項
  1. AddSingleton:每次都獲取同一個例項

當大家已經過了百度每種注入方式的使用場景後,有沒有萌生出一個新的問題:就是一個作用域(Scoped)服務中注入一個瞬時(Transient)服務時,瞬時服務中的值還會每次都變化嗎?
出現這個問題是因為:我有兩個服務,一個是資料處理服務A(Scoped),一個是從Redis取資料的服務B(Transient),本來想的是處理資料時每次從Redis中新開例項來取資料,但是事與願違每次Redis例項總是不變,然後自己下載了官方的示例程式研究了一下,在此做個記錄,以下為了好區分,我就以主次服務來區分,一共分為幾下幾種情況:

1. 主服務為Scoped,次服務為Transient時

配置
結果
由圖可知,在這種情況下瞬時服務是沒用的,兩次的結果是一樣的。原因是因為scoped服務只有第一次執行的時候是走建構函式的,後面再建立都是直接賦值,而不是建立新物件不走建構函式因此值也不會改變。

2. 主服務為Singleton,次服務為Scoped時

配置
結果
這種情況直接報錯(Cannot Consume Scoped Service From Singleton),這是因為Core防止我們陷入這樣的一個陷阱,怕我們誤以為每次請求都會建立一個新的例項

3. 主服務為Singleton,次服務為Transient時

配置
結果
發現結果也是一樣的,而且並沒有向上面一樣報錯,難道微軟粑粑就不怕我們陷入這樣的一個陷阱嗎?我個人覺得原因是這樣的:Scoped方式是每個請求時建立一個新的例項,但Transient是每個請求中呼叫每個服務都會建立一個新的例項,在一次請求中,如果在Singleton中還使用Scoped的話,Scoped和Singleton的意義是一樣的(比如我這次請求的時候正常Scoped產生的值是1,我在其它服務中使用的值都將是1,但是在Singleton中儲存的值還是0,這樣就會產生歧義),但如果Singleton中使用Transient的話只針對當前服務中是唯一的,呼叫其它服務的時候Transient還是會建立新的例項,因此在其它服務中就不會有其它問題(簡單來講就是預設我在Singleton中呼叫Transient時我就預設產生的值就為0,反正我每次請求都會產生新的值,無所謂是0還是1,還是2了),雖然沒有報錯但我們還是要避免這樣使用。

微信關注我哦!(轉載註明出處)關注我哦

相關文章