重新整理 .net core 實踐篇————依賴注入應用之生命法則[三]


前言

該章演示依賴注入中,對象的釋放行為。

緊接上文表示,演示:

services.AddSingleton<IMySingletonService, MySingletonService>();
services.AddSingleton<IMySingletonService>(new MySingletonService());
services.AddSingleton<IMySingletonService>(ServiceProvider =>
{
	return new MySingletonService();
});

這三種生命周期的注入方式的不同,他們的生命周期不同。

主要是兩條法則:

  1. DI 只負責釋放由其創建的對象實例,DI 在容器或者子容器釋放時,釋放由其創建的對象的實例。

  2. 不要在根容器中獲取瞬時服務,不要在根容器中獲取瞬時服務,不要在根容器中獲取瞬時服務,重要的事情說三遍。

正文

第一條法則證明公理:

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 還是比較重要的,一般大一點的項目都會用上,比較方便吧。

上述只是個人整理,如果錯誤,望請指教。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM