跟我一起学.NetCore之依赖注入作用域和对象释放
前言
????上一小節簡單闡述了依賴注入及Asp.NetCore中自帶依賴注入組件的常規用法,其中提到容器管控了自己創建對象的生命周期,包含了三種生命周期:Singleton、Scoped、Transient,?對于Singleton、Transient相對于Scoped來說比較好理解,其實這里面有一個作用域的概念,也可以理解為根容器和子容器的范圍;上一小節中有一個例子中說到,當注入的生命周期為Scoped的時,在同一個請求內,注入的對象都是同一個,這里Asp.NetCore將每個請求作為了一個作用域,在此作用域內,生命周期為Scoped的對象就是同一個;下面簡單說說作用域和對象釋放的常規知識點;
正文
????作用域這里可以理解為服務范圍,由IServiceScope承載,如其源代碼所示,每一個服務范圍內都一個根容器,如下所示:
//// 摘要:// /// The System.IDisposable.Dispose method ends the scope lifetime. Once Dispose// /// is called, any scoped services that have been resolved from /// Microsoft.Extensions.DependencyInjection.IServiceScope.ServiceProvider// will be /// disposed. ///public interface IServiceScope : Object, IDisposable{//?IServiceProvider?即代表容器//// 摘要:// /// The System.IServiceProvider used to resolve dependencies from the scope.// ///IServiceProvider ServiceProvider{get;}}????每一個服務范圍內可以通過自身IServiceProvider創建對應的子作用域,而任何一個子作用域的IServiceProvider都有對根容器的引用,如下圖結構:
? ? 每一個IServiceProvider中都會將其創建的對象存入列表中,針對于繼承與IDisposable接口的類型對象會單獨存放在一個列表中,當作用域IServiceScope對象的Dispose方法被調用時,最終對應IServicePorvider對應的對象列表也會清空,針對于繼承與IDisposable類型的對象會調用其Dispose方法;最后導致對應作用域下容器創建的對象成為垃圾對象,被GC給回收;
????在Asp.NetCore中,框架默認將其分有根作用域(與引用程序同生命周期)和請求作用域(每一個請求一個作用域),通常也會稱其為根容器和請求容器,名稱分別為ApplicationServices和RequestServices,在程序中獲取方式如下:
????通過IApplicationBuilder對象可以獲取ApplicationServices
????通過HttpContext.RequestServices獲取RequestServices
????作用域簡單舉例,在請求作用域下再創建子作用域,分別查看對應不同生命周期對象是否一致,新建一個WebApi項目,針對三個生命周期添加了對應文件,結構如下:
????
對應紅框內的文件內容如下:
???????細心的小伙伴可能會看到,每個實現類里面都繼承了IDisposable接口,這主要是后面顯示釋放用的,這里先不管;編輯好以上內容之后就將其進行注冊,如下:
????接下來就是使用了,這里通過這Action中使用,在當前的請求作用域下創建子作用域,對比每一個生命周期對象,如代碼所示:
????運行,進行請求,看打印結果:
????
????對于Singleton來說始終不變,因為其是跟隨根容器生命周期,引用程序退出才釋放;
????對于Scoped來說只要在自己的作用域內就是單例的;
????對于Transient來說始終創建;
????以上一直在說釋放,下面利用繼承IDisposable接口釋放時會調用對應Dispoable方法的原理簡單演示各個生命周期的釋放時機;在Controller中增加幾個Action方法,如下:
????這里使用IHostApplicationLifetime中的StopApplication模擬關閉程序釋放單例下的對象;運行看效果:
? ??使用坑:不要從根容器中獲取Transient生命周期的對象,因為通過根容器創建的對象不會回收,除非等到應用程序退出,這樣會導致內存泄露;如下演示:
????
新增Action方法:
運行,發送請求看結果:
總結
????作用域及對象釋放就簡單說這么多,容器只管理自己創建出來的對象生命周期;下一節說說使用第三方組件擴展依賴注入功能;
總結
以上是生活随笔為你收集整理的跟我一起学.NetCore之依赖注入作用域和对象释放的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 跟我一起学.NetCore之依赖注入
- 下一篇: 大揭秘| 我司项目组Gitlab Flo