06 | 作用域与对象释放行为

接下来,把服务切换为单例模式,通过工厂的方式

services.AddSingleton<IOrderService>(p => new DisposableOrderService());

启动程序,输出如下:

=======1==========
=======2==========
接口请求处理结束

可以看到代码实际上不会被释放

如果切换为瞬时模式,通过工厂的方式

services.AddTransient<IOrderService>(p => new DisposableOrderService());

启动程序,输出如下:

=======1==========
DisposableOrderService Disposed:12021664
DisposableOrderService Disposed:32106157
=======2==========
接口请求处理结束
DisposableOrderService Disposed:3165221
DisposableOrderService Disposed:13048313

这里可以看到,获取四个服务并且释放掉

接下来把服务调整为自己创建,并注册进去

var service = new DisposableOrderService();
services.AddSingleton<IOrderService>(service);

同样我们也不会得到释放的输出

也就是说,通过这种方式注册,容器不会管理对象的生命周期

如何识别这个区别呢?

在控制器中注入 IHostApplicationLifetime 接口

这个接口的作用是用来管理整个应用程序的生命周期

它有一个方法 StopApplication

也就是说它可以把整个应用程序关掉

接着,通过手工关掉的方式看一下应用程序关闭时会不会把单例对象释放掉

[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;
}

首先用自己创建对象的方式

var service = new DisposableOrderService();
services.AddSingleton<IOrderService>(service);

启动程序

输入 ?stop=true

https://localhost:5001/weatherforecast?stop=true

输出如下:

...
DependencyInjectionScopeAndDisposableDemo.exe (进程 16884)已退出,代码为 0。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .

如果单例由容器来管理,切换回普通注册方式

services.AddSingleton<IOrderService, DisposableOrderService>();

启动程序

输入 ?stop=true

https://localhost:5001/weatherforecast?stop=true

输出如下:

Application is shutting down...
接口请求处理结束
DisposableOrderService Disposed:23399238

对象释放,应用程序退出

这里说明单例的服务都是注册在根容器里面

根容器的释放意味着需要在整个应用程序退出时释放

这个时候它会释放自己所管理的所有的 IDisposable 的对象

这里面有一个非常需要注意的坑:

假如把服务注册成瞬时的

services.AddTransient<IOrderService, DisposableOrderService>();

然后又在根容器里面去获取这个对象

var s = app.ApplicationServices.GetService<IOrderService>();

这意味着在根容器去持续的创建 IOrderService,但是由于根容器只会在应用程序整个退出时回收,也就意味着这些对象会一直积累在应用程序内

调整控制器,不获取 IOrderService

[HttpGet]
public int Get([FromServices]IHostApplicationLifetime hostApplicationLifetime,[FromQuery]bool stop = false)
{if (stop){hostApplicationLifetime.StopApplication();}return 1;
}

仅仅在根容器获取一次

var s = app.ApplicationServices.GetService<IOrderService>();

这样运行起来,每次请求(点击刷新)的话,整个输出是不会有内容的,因为我们没有在子容器里面去获取对象

但实际上当我们退出的时候,会发现确实有一个实例被释放掉了

DisposableOrderService Disposed:7511460

也就是说,实现了 IDisposable 接口的服务,如果时注册瞬时的,又在根容器去做操作,它会一直保持到应用程序退出的时候,才能够被回收掉

.NET Core开发实战(第6课:作用域与对象释放行为)--学习笔记(下)相关推荐

  1. .NET Core开发实战(第6课:作用域与对象释放行为)--学习笔记(上)

    06 | 作用域与对象释放行为 作用域主要由 IServiceScope 这个接口来承载 对于实现 IDisposable 类的实例的对象,容器会负责对其生命周期进行管理,使用完毕之后,他会释放这些对 ...

  2. .NET Core开发实战(第5课:依赖注入:良好架构的起点)--学习笔记(上)

    05 | 依赖注入:良好架构的起点 为什么要使用依赖注入框架 借助依赖注入框架,我们可以轻松管理类之间的依赖,帮助我们在构建应用时遵循设计原则,确保代码的可维护性和可扩展性 ASP.NET Core ...

  3. .NET Core开发实战(定义API的最佳实践)Source Generators版

    前言 极客时间上的<.NET Core开发实战>是一门非常好的课程,作者肖伟宇在第31课(https://time.geekbang.org/course/detail/100044601 ...

  4. ASP.NET Core分布式项目实战(详解oauth2授权码流程)--学习笔记

    最近公司产品上线,通宵加班了一个月,一直没有更新,今天开始恢复,每日一更,冲冲冲 任务13:详解oauth2授权码流程 我们即将开发的产品有一个用户 API,一个项目服务 API,每个服务都需要认证授 ...

  5. ASP.NET Core分布式项目实战(Consent Controller Get请求逻辑实现)--学习笔记

    任务20:Consent Controller Get请求逻辑实现 接着上一节的思路,实现一下 ConsentController 根据流程图在构造函数注入 IClientStore,IResourc ...

  6. 大数据开发工程师基本功修炼之史上最全Linux学习笔记(建议)

    我正在参加年度博客之星评选,请大家帮我投票打分,您的每一分都是对我的支持与鼓励. 2021年「博客之星」参赛博主:Maynor大数据 (感谢礼品.红包免费送!) https://bbs.csdn.ne ...

  7. 跟我一起学.NetCore之依赖注入作用域和对象释放

    前言 上一小节简单阐述了依赖注入及Asp.NetCore中自带依赖注入组件的常规用法,其中提到容器管控了自己创建对象的生命周期,包含了三种生命周期:Singleton.Scoped.Transient ...

  8. C/C++ 开发 boost 库参考手册整理(2) 【学习笔记】

    文档声明: 以下资料均属于本人在学习过程中产出的学习笔记,如果错误或者遗漏之处,请多多指正.并且该文档在后期会随着学习的深入不断补充完善.感谢各位的参考查看. 笔记资料仅供学习交流使用,转载请标明出处 ...

  9. 【全栈之巅】Node.js + Vue.js 全栈开发王者荣耀手机端官网和管理后台学习笔记(4.1-4.10)

    [全栈之巅]Node.js + Vue.js 全栈开发王者荣耀手机端官网和管理后台学习笔记(4.1-4.10) 本项目是 学习Bilibili 全栈之巅 视频教程相关源码和体会 https://git ...

最新文章

  1. 谷歌花35元就“骗”走刷脸数据:黑人为主,霸王条款无限使用,为强化新手机能力...
  2. linux php ldap扩展,php_ldap域集成模块安装-159
  3. jsp中不能正常显示图片+不能正常显示bootstrap字体图标
  4. 为什么parsefloat加出来还是字符串_为什么酒店的包子做的这么好吃?里面加了什么说出来你可能不信...
  5. IOS9+基础之警报框弹出和操作表弹出
  6. 【MySQL】redo log --- 刷入磁盘过程
  7. 内存泄露和溢出的区别_Java 中的内存溢出和内存泄露是什么?我给你举个有味道的例子?...
  8. 10_隐马尔科夫模型HMM2_统计学习方法
  9. Soul网关源码阅读(六)请求类型探索
  10. 通过思科构造局域网_从Cisco DNA中心的管理的和设置的非结构Catalyst 9800无线局域网控制器...
  11. 软件架构发展的几个阶段
  12. systemctl的使用
  13. 编程基本功:知识、经历可以获得,能力不可能提升
  14. 小规模纳税人季度申报流程指导
  15. PhotoScissors 6 for Mac(mac抠图软件)
  16. 心理学实验必备 | 脑电实验流程及注意事项
  17. 我在舒舍的短租生活之旅
  18. 搜狗输入法,怎么打声调?
  19. DB DBS 和DBMS区别
  20. IP数据报分片原因(详细)及其步骤

热门文章

  1. JS iframe父子页面元素调用方法 window parent top 解释
  2. 超棒的在线Bootstrap主题编辑工具 - lollytin
  3. i-doIT 0.9.9-7发布 CMDB配置管理数据库
  4. tabnavigator_使用TabNavigator在Firefox中享受桌面Alt-Tab样式导航
  5. nodejs和Vue和Idea
  6. linkbox php,win10 docker-toolsbox 搭建php开发环境的教程
  7. ETL工具kettle的组件--生成记录
  8. vue vue-router vuex element-ui axios 写一个代理平台的学习笔记(十一)构思商品页面...
  9. “爱思助手”曝为iOS木马:可绕过苹果DRM机制
  10. mysql出现连接错误不识别 utf8mb4