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

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

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

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

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

无论如何 – 这是它的工作原理。

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

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

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

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

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

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

另一件事是你调用ResolveRelease 。 你应该只ReleaseResolve

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

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