欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

依赖注入生命周期

程序员文章站 2023-12-28 10:30:40
...

介绍

  • 依赖注入只负责由其创建的对象实例

  • 容器或者子容器释放的时候,会释放由其创建的对象实例。

推荐使用容器来管理我们的对象的创建和释放。

操作

为了演示,我们创建一个UserService,并让该Service继承IDisposable

public class UserService : IUserService, IDisposable
{
    public int Sum(int x, int y)
    {
        return x + y;
    }

    public void Dispose()
    {
        Console.WriteLine($"UserService服务被释放  {this.GetHashCode()}");
    }
}
public interface IUserService
{
    int Sum(int x, int y);
}

在控制器中我们通过FromServices去注入IUserService

[HttpGet]
public string Get([FromServices] IUserService userService, [FromServices] IUserService userService2)
{
    Console.WriteLine($"当前创建的UserService  {userService.GetHashCode()}");
    Console.WriteLine($"当前创建的UserService2  {userService2.GetHashCode()}");

    //为当前请求创建一个子容器,一次请求会创建一次
    using (var scope = HttpContext.RequestServices.CreateScope())
    {
        var service = scope.ServiceProvider.GetRequiredService<IUserService>();
        Console.WriteLine($"子容器创建的UserService  {service.GetHashCode()}");

        Console.WriteLine($"子容器创建的UserService处理完毕");
    }

    Console.WriteLine("接口处理完毕 ");
    return DateTime.Now.ToString();
}

瞬时生命周期

现在我们将刚才的服务注册为瞬时生命周期

services.AddTransient<IUserService, UserService>();

运行查看对象释放的时机,输出结果

// 第一次请求结束
当前创建的UserService  35827753
当前创建的UserService2  4419630
子容器创建的UserService  40124269
子容器创建的UserService处理完毕
UserService服务被释放  40124269
接口处理完毕
UserService服务被释放  4419630
UserService服务被释放  35827753
    
// 第二次请求结束       
当前创建的UserService  17653682
当前创建的UserService2  42194754
子容器创建的UserService  15688314
子容器创建的UserService处理完毕
UserService服务被释放  15688314
接口处理完毕
UserService服务被释放  42194754
UserService服务被释放  17653682

通过结果可以得出结论,瞬时生命周期对象的释放在这次请求结束的时候释放,并且一次请求可能产生多次实例,多次请求产生多次实例。

但是如果我们是在跟容器进行获取的瞬时服务,那么它就不是请求结束的时候释放了。

ConfigureServices中注册

services.AddTransient<IUserService,UserService>();

Configure中配置

var servise = app.ApplicationServices.GetService<IUserService>();
Console.WriteLine(servise.Sum(1, 2));

会在项目启动的时候进行输出,中间调用接口并不会释放服务,当程序关闭的时候释放服务

info: Microsoft.Hosting.Lifetime[0]
      Application is shutting down...
UserService服务被释放  30995104

范围生命周期

现在我们将刚才的服务注册为范围生命周期

services.AddScoped<IUserService, UserService>();
// 或者
services.AddTransient<IUserService>(p => new UserService());

运行查看对象释放的时机,输出结果

// 第一次请求结束
当前创建的UserService  43182754
当前创建的UserService2  43182754
子容器创建的UserService  49229074
子容器创建的UserService处理完毕
UserService服务被释放  49229074
接口处理完毕
UserService服务被释放  43182754
    
// 第二次请求结束    
当前创建的UserService  28952583
当前创建的UserService2  28952583
子容器创建的UserService  51571199
子容器创建的UserService处理完毕
UserService服务被释放  51571199
接口处理完毕
UserService服务被释放  28952583

通过结果可以得出结论,范围生命周期对象的释放在这次请求结束的时候释放,并且一次请求内只产生一次实例,多次请求产生多次实例。

单例生命周期

现在我们将刚才的服务注册为范围生命周期

services.AddSingleton<IUserService, UserService>();

运行查看对象释放的时机,输出结果

// 第一次接口请求结束
当前创建的UserService  26224738
当前创建的UserService2  26224738
子容器创建的UserService  26224738
子容器创建的UserService处理完毕

// 第二次
接口处理完毕
当前创建的UserService  26224738
当前创建的UserService2  26224738
子容器创建的UserService  26224738
子容器创建的UserService处理完毕
接口处理完毕

// 当Ctrl+C关闭程序
info: Microsoft.Hosting.Lifetime[0]
      Application is shutting down...
UserService服务被释放  13588007

通过结果可以得出结论,单例生命周期对象的释放在程序停止运行的时候释放,并且多次请求只产生一次相同的实例。

当服务是我们自己创建的然后再次测试

var userService = new UserService();
services.AddSingleton<IUserService>(userService);

只有单例模式下支持该方式,可能故意限制的

输出结果

// 第一次请求
当前创建的UserService  62006733
当前创建的UserService2  62006733
子容器创建的UserService  62006733
子容器创建的UserService处理完毕
接口处理完毕

// 第二次请求
当前创建的UserService  62006733
当前创建的UserService2  62006733
子容器创建的UserService  62006733
子容器创建的UserService处理完毕
接口处理完毕

//关闭程序
info: Microsoft.Hosting.Lifetime[0]
      Application is shutting down...

通过结果得出结论,我们自己创建的实例,并不通过容器管理,也就是说不会自己释放。

小知识

如何实现通过调用接口关闭应用程序

[HttpGet]
public void StopApplication([FromServices] IHostApplicationLifetime lifetime)
{
    lifetime.StopApplication();
}

通过注入IHostApplicationLifetime然后执行StopApplication来停止应用程序。

相关标签: .NET c#

上一篇:

下一篇: