控制作用域和生命周期

这个有一篇学习Autofac控制作用域和生命周期很好的文章 Nick Blumhardt's Autofac lifetime primer. 里面有很多东西可以学习, 并且有很多混合的概念, 因此我们尝试在这边对该文做些补充.

回忆下 注册章节 , 你向容器中添加了一个实现 服务组件 . 最后 解析服务 并且使用这些服务的实例来完成一些事.

服务的 生命周期 是指服务实例在你的应用中存在的时长 - 从开始实例化到最后 释放 结束. 例如, 如果你 "new up" 了一个 实现 IDisposable 的对象并且之后调用了它的 Dispose() 方法, 对象的生命周期是从你实例化一直到释放 (或者是被垃圾回收, 如果你没有提前释放它的话).

服务的 作用域 是指它在应用中能共享给其他组件并被消费的作用域. 例如, 在你的应用中你有个全局的静态单例 - 该全局对象实例的 "作用域" 将会是整个应用. 另一方面, 如果你在一个 for 循环中创建了引用了全局单例的一个局部变量 - 那么这个局部变量就拥有比全局变量小很多的作用域.

Autofac中 生命周期作用域 的概念其实是把这两个概念组合在了一起. 实际上, 生命周期作用域等同于你应用中的一个工作单元. 一个工作单元将会在开始时启动生命周期作用域, 然后需要该工作单元的服务被从生命周期作用域中解析出. 当你解析服务时, Autofac将会追踪被解析的可释放/可销毁 (IDisposable) 组件. 在工作单元最后, 你释放了相关的生命周期作用域然后Autofac将会自动清理/释放那些被解析的服务.

生命周期控制作用域的两个要素是共享和释放.

  • 生命周期作用域是可嵌套的并且它们控制了组件如何共享. 例如, 一个 "单例" 服务也许会从根生命周期解析因为每个独立的工作单元会需要它们各自的服务实例. 你可以通过 注册时设置实例作用域 决定组件如何共享.
  • 生命周期作用域追踪可释放对象并且当生命周期作用域被释放同时释放它们. 例如, 如果你有个实现 IDisposable 的组件并且你从生命周期中解析了它, 生命周期作用域将会保持住它并且替你释放它, 这样你的服务消费者就不必知道它的内在具体实现. 你有能力选择控制该行为或者添加一个新的释放行为.

在你的应用中, 最好记住以下概念这样就能有效使用你的资源.

永远从一个生命周期作用域而不是从根容器中解析服务. 由于生命周期作用域有追踪可释放资源的性质, 如果你从一个容器 ("根生命周期作用域") 中解析了太多组件, 无意间也许你就会造成内存泄露. 根生命周期会在它存在的时间 (通常是应用的生命周期) 内保持住可释放组件因此它也能释放它们. 你可以选择性的改变释放行为, 但从作用域内解析是个良好的实践. 如果Autofac检测到使用单例或共享组件, 它会自动把它们安放在一个合适的追踪作用域之内.

让我们看下web类应用, 把它作为一个更好阐述生命周期作用域的具体例子. 假设有以下场景:

  • 你有一个全局的单例logging服务.
  • 两个请求同时进入到web应用中.
  • 每个请求是一个逻辑上的 "工作单元" 并且每个请求需要它们各自的order processing service.
  • 每个order processing service 要用 logging service 记录信息.

在这种场景中, 你有一个根作用域, 包含单例的logging service并且每个请求有一个子生命周期, 每个有它们自己的order processing service:

+---------------------------------------------------+
|                 Autofac Container                 |
|                Root Lifetime Scope                |
|                                                   |
|                  Logging Service                  |
|            (shared across all requests)           |
|                                                   |
| +----------------------+ +----------------------+ |
| |  First Request Scope | | Second Request Scope | |
| |                      | |                      | |
| |   Order Processor    | |   Order Processor    | |
| +----------------------+ +----------------------+ |
+---------------------------------------------------+

每个请求结束时, 请求的生命周期也结束并且各自的订单处理程序得到释放. logging service作为一个单例, 将会保持存在并以备后续请求共享.

你可以通过 Nick Blumhardt's Autofac lifetime primer 一文深入了解生命周期作用域相关内容.

更多生命周期作用域相关章节: