Castle Windsor - 我是否必须释放单件或非一次性瞬态物体?

blu*_*ing 11 c# castle-windsor

城堡维基说,在几个地方,我应该始终调用container.Release()通过容器解决组件.对于复杂的生活方式管理技术(例如LifeStyle.Pooled)或使用专门设施时,这显然是有意义的......

但是,我真的必须释放单件(直到容器被处置)和非一次性瞬态物体?如果我逐步调用Release()调用瞬态对象或单例,这些调用似乎是多余的 - .eg在瞬态对象未实现IDisposable的情况下,内核只是注意到它没有跟踪对象并返回...

似乎存在"组件负担"的概念来跟踪在解析瞬态对象时可能构造的其他一次性组件的"间接"引用.我知道如果你不知道它们是否具有这种间接依赖关系,就必须释放瞬态对象.这是"敦促"所有Castle用户始终发布组件的主要原因吗?

Krz*_*mic 21

Castle Wiki在这里有点严格 - 试图安全而不是抱歉.它可能会使用一些重写.

无论如何 - 这是它的工作原理.

Windsor(默认情况下)跟踪大多数组件,它保留对它们的引用,这会阻止垃圾收集器收集它们.这不是一个错误 - 它是一个功能,是一个非常有用和强大的功能.在大多数情况下,您不应该假设是否会跟踪组件.还将跟踪具有一次性依赖性的非一次性组件.这通常是规则:" Windsor中的默认发布策略会跟踪其某些依赖项本身具有任何解除授权步骤的组件 ".

现在,这是生命发挥作用的部分.

  • 单例 - 根据定义,单例在容器的上下文中是"全局的" - 它们在您第一次请求它们时生成,并在容器的其余生命周期中生效(这意味着直到容器被处置).如果您看到文档,它实际上说释放单身实际上并没有做任何事情.只有当容器被处置时,才能调用您的生命周期组件的退役问题.

  • Per(上下文:Web请求/ WCF会话/) - 由于对象是在定义良好的上下文中共享的,具有良好定义的结束,因此上下文的末尾将负责释放您的组件.

  • 瞬态 - 这就是真正的问题可能蔓延的地方.由于瞬态组件没有任何终结任意生命终结,你可以在应用程序的生命周期中产生大量的实例,除了明确并且对容器"嘿,我不会再使用这个物体,随意摆脱它,感谢所有的鱼."

现在,文档建议始终释放组件的原因是使用组件的代码不应该真正知道组件的生命周期是什么.情况并非总是如此,并且通常在应用中存在"自然地"适合生活方式的组件.但总的来说,就像我说的那样是安全而不是抱歉.

另一件事是你打电话给ResolveRelease.你应该只Release对你有所帮助Resolve.

当您以与我的方式类似的方式使用容器,您可能不必Release在代码中的任何位置调用.你将是Resolve你的根,但Dispose容器本身将负责释放它.您可能还会通过类型化工厂隐式解析其他组件,在这种情况下,您也应该(通过工厂)释放它们,但通常是这样.

所以最终的结果是,它并不像最初听起来那么可怕.

  • 对Krzysztof解释的规则的一个警告是,如果你自己创建一个对象并用容器注册你的实例(而不是让容器为你创建一个实例),那么容器将把该实例的生命周期的管理权交给你.即使您将其注册为单件,当您丢弃容器时,容器也不会丢弃它. (4认同)