前言
該章演示依賴注入中,對象的釋放行為。
緊接上文表示,演示:
services.AddSingleton<IMySingletonService, MySingletonService>();
services.AddSingleton<IMySingletonService>(new MySingletonService());
services.AddSingleton<IMySingletonService>(ServiceProvider =>
{
return new MySingletonService();
});
這三種生命周期的注入方式的不同,他們的生命周期不同。
主要是兩條法則:
-
DI 只負責釋放由其創建的對象實例,DI 在容器或者子容器釋放時,釋放由其創建的對象的實例。
-
不要在根容器中獲取瞬時服務,不要在根容器中獲取瞬時服務,不要在根容器中獲取瞬時服務,重要的事情說三遍。
正文
第一條法則證明公理:
public interface ITestService
{
}
public class TestService:ITestService,IDisposable
{
public void Dispose()
{
Console.WriteLine($"DisposableTestService Disposed:{this.GetHashCode()}");
}
}
注冊:
services.AddSingleton<ITestService>(new TestService());
然后測試:
[HttpGet]
public int GetService([FromServices] ITestService testService,[FromServices]IHostApplicationLifetime hostApplicationLifetime,[FromQuery]bool stop = false)
{
if (stop)
{
hostApplicationLifetime.StopApplication();
}
return 1;
}
結果:
應用離開的時候並沒有調用我們的Dispose方式。
那么換一種注冊方式:
services.AddSingleton<ITestService, TestService>();
結果如下:
應用程序離開的時候會調用我們的dispose。
再換一種方式:
services.AddSingleton<ITestService>(serviceProvider =>
{
return new TestService();
});
也會主動調用這個dispose。
證明不要在根容器中獲取瞬時服務:
理論上離開區域那么應該會調用dispose 釋放,但是情況和我們想的不一樣。
測試代碼:
[HttpGet]
public int GetService([FromServices]IHostApplicationLifetime hostApplicationLifetime,[FromQuery]bool stop = false)
{
if (stop)
{
hostApplicationLifetime.StopApplication();
}
return 1;
}
當訪問stop參數不為true
當訪問stop參數為true,也就是關閉服務的時候:
說明根容器獲取的瞬時對象,並沒有在離開區域內釋放,而是在容器回收的時候才釋放。間接的說明一個問題,這個對象起碼被我們的根容器間接引用了,這里埋個坑,后面系列解釋為什么。
那么為什么我們從FromServices中獲取的ITestService會被釋放呢?
這是應為,其實每一次http訪問都會創建一個子容器來保證隔離:
[HttpGet]
public int GetService([FromServices]IHostApplicationLifetime hostApplicationLifetime,[FromQuery]bool stop = false)
{
using (IServiceScope scope = HttpContext.RequestServices.CreateScope())
{
var obj=scope.ServiceProvider.GetService<ITestService>();
}
if (stop)
{
hostApplicationLifetime.StopApplication();
}
return 1;
}
結果:
結
下一節介紹Autofac,主要介紹一下什么情況我們需要使用第三方的Autofac,它給我們帶來什么東西,或者給我們帶來什么方便,以及如何操作。Autofac 還是比較重要的,一般大一點的項目都會用上,比較方便吧。
上述只是個人整理,如果錯誤,望請指教。