.NET Core development actual combat (Lesson 6: Scope and target release behavior) - Study Notes (under)

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]) 。

Guess you like

Origin www.cnblogs.com/MingsonZheng/p/12343902.html