06 | Scope and target release behavior
Next, the service mode is switched to the single embodiment, by way of the plant
services.AddSingleton<IOrderService>(p => new DisposableOrderService());
Start the program, the output is as follows:
=======1==========
=======2==========
接口请求处理结束
We can actually see the code will not be released
If mode switching is instantaneous, the factory by way of
services.AddTransient<IOrderService>(p => new DisposableOrderService());
Start the program, the output is as follows:
=======1==========
DisposableOrderService Disposed:12021664
DisposableOrderService Disposed:32106157
=======2==========
接口请求处理结束
DisposableOrderService Disposed:3165221
DisposableOrderService Disposed:13048313
Here you can see, access and freed four service
Next adjust the service to create your own, go and register
var service = new DisposableOrderService();
services.AddSingleton<IOrderService>(service);
Similarly, we will not get the output released
In other words, by registering in this way, it does not manage the life cycle of a container object
How to recognize this difference does it make?
Injection IHostApplicationLifetime interface controller
The role of the interface is used to manage the entire application lifecycle
It has a method StopApplication
That it can turn off the entire application
Then, turn off the manual way look at the singleton object will not be freed when the application is closed
[HttpGet]
public int Get([FromServices] IOrderService orderService,
[FromServices] IOrderService orderService2,
[FromServices]IHostApplicationLifetime hostApplicationLifetime,
[FromQuery]bool stop = false)
{
Console.WriteLine("=======1==========");
// HttpContext.RequestServices
// 是当前请求的一个根容器
// 应用程序根容器的一个子容器
// 每个请求会创建一个容器
using (IServiceScope scope = HttpContext.RequestServices.CreateScope())
{
// 在这个子容器下面再创建一个子容器来获取服务
var service = scope.ServiceProvider.GetService<IOrderService>();
var service2 = scope.ServiceProvider.GetService<IOrderService>();
}
Console.WriteLine("=======2==========");
if (stop)
{
hostApplicationLifetime.StopApplication();
}
Console.WriteLine("接口请求处理结束");
return 1;
}
First, a way to create their own objects
var service = new DisposableOrderService();
services.AddSingleton<IOrderService>(service);
starting program
Enter? Stop = true
https://localhost:5001/weatherforecast?stop=true
Output is as follows:
...
DependencyInjectionScopeAndDisposableDemo.exe (进程 16884)已退出,代码为 0。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .
If the vessel is managed by a single embodiment, switching back to normal mode register
services.AddSingleton<IOrderService, DisposableOrderService>();
starting program
Enter? Stop = true
https://localhost:5001/weatherforecast?stop=true
Output is as follows:
Application is shutting down...
接口请求处理结束
DisposableOrderService Disposed:23399238
The object is released, the application exits
Single embodiment described herein services are registered in the root inside the container
Release means that the root of the container at the time of the release of the entire application exits
This time it will release all managed by their own IDisposable objects
And there are a great pit to note:
If the service is registered as a momentary
services.AddTransient<IOrderService, DisposableOrderService>();
Then the root container inside to acquire the object
var s = app.ApplicationServices.GetService<IOrderService>();
This means that the root container to create sustained IOrderService, but because the root container will be recovered at the entire application exits, which means these objects have been accumulated within the application
Adjust the controller, do not get IOrderService
[HttpGet]
public int Get(
[FromServices]IHostApplicationLifetime hostApplicationLifetime,
[FromQuery]bool stop = false)
{
if (stop)
{
hostApplicationLifetime.StopApplication();
}
return 1;
}
Only get once in a root container
var s = app.ApplicationServices.GetService<IOrderService>();
This up and running, every request (hit refresh), then the entire output will not have content, because we did not go get an object inside a container in a sub
But in fact when we exit, you will find there is indeed an instance is freed up
DisposableOrderService Disposed:7511460
In other words, the service implements the IDisposable interface, if the registration instantaneous, but also at the root of the container to do the operation, it will remain to when the application exits, it can be recycled out
This work is Creative Commons Attribution - NonCommercial - ShareAlike 4.0 International License Agreement for licensing.
欢迎转载、使用、重新发布,但务必保留文章署名 郑子铭 (包含链接: http://www.cnblogs.com/MingsonZheng/ ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。
如有任何疑问,请与我联系 ([email protected]) 。