依赖注入生命周期

介绍

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

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

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

操作

为了演示,我们创建一个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来停止应用程序。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值