我有一个实现 IDisposable 的对象,该对象在 Windsor Container 中注册,我想处理它,以便调用它的 Dispose 方法,下次调用 Resolve 时它会获取一个新实例。
做
container.Release(obj);
立即自动调用 Dispose()?还是我需要做
obj.Dispose();
container.Release(obj);
在文档中找不到任何关于 Release 究竟是做什么的
编辑:
有关我运行的测试结果,请参阅下面的答案。现在问题变成了,如何强制容器释放具有单例生命周期的组件实例?这只需要在一个地方完成,编写自定义生命周期似乎太重了,没有内置的方法吗?
最佳答案
我认为人们在使用 Windsor 容器时并没有真正意识到这一点——尤其是经常出现的 。令人惊讶一次性 transient 组件在内核的生命周期内被容器保留直到它被释放的行为,除非你自己释放它们——尽管它被记录了——看看 here - 但要快速引用:
the MicroKernel has a pluggable release policy that can hook up and implement some routing to dispose the components. The MicroKernel comes with three IReleasePolicy implementations:
- AllComponentsReleasePolicy: track all components to enforce correct disposal upon the MicroKernel instance disposal
- LifecycledComponentsReleasePolicy: only track components that have a decommission lifecycle associated
- NoTrackingReleasePolicy: does not perform any tracking
You can also implement your own release policy by using the interface IReleasePolicy.
您可能会发现更简单的方法是将策略更改为 NoTrackingReleasePolicy 然后自己处理处置 - 这也有潜在风险,但如果您的生活方式在很大程度上是短暂的(或者当您的容器被处置时,您的应用程序无论如何都将关闭),这可能没什么大不了的。但是请记住,任何已经注入(inject)单例的组件都将持有一个引用,因此您最终可能会在尝试“刷新”您的单例时导致问题 - 这似乎是一种不好的做法,我想知道您是否可以避免不得不首先通过改进应用程序的组合方式来做到这一点。
其他方法是使用自己的退役实现来构建自定义生命周期(因此释放单例实际上会处置组件,就像 transient 生命周期所做的那样)。
或者,另一种方法是使用单例生活方式在容器中注册您的服务的装饰器,但您在容器中注册的实际底层服务具有 transient 生活方式 - 然后当您需要刷新组件时,只需处置持有的 transient 底层组件由装饰器替换它并用新解决的实例替换它(使用 components 键而不是服务来解决它,以避免获取装饰器) - 这避免了其他单例服务(未“刷新”)的问题到过时的服务上,这些服务已经被处理使它们无法使用,但确实需要一些强制转换等才能使其工作。
关于.net - 温莎容器 : How to force dispose of an object?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/85183/