我正在使用Castle Windsor Typed Factory。在我们的注册码中,它被设置为可以创建一个Transient组件:
container.AddFacility<TypedFactoryFacility>();
container.Register(Component.For<IThingFactory>().AsFactory());
container.Register(Component.For<IThing>().ImplementedBy<TransientObject>().Named("TransientObject").LifeStyle.Transient);
根据我对the Castle Windsor Typed Factory documentation的理解,我认为Transient对象必须由Typed Factory方法释放,否则Typed Factory会保留对该对象的引用。我尝试通过编写使用this StackOverflow article中解释的方法的测试来证明这一点。
但令我惊讶的是它实际上并没有失败,这意味着虽然我没有将瞬态物体释放回工厂,但它仍然可以被GC收回。我担心也许我的测试会产生误导,而且确实存在泄漏。
所以我的问题是:我的测试是错误的,还是文档错了?
以下是测试:
var factory = container.Resolve<IThingFactory>();
WeakReference reference = null;
new Action(() =>
{
var service = factory.GetTransientObject();
reference = new WeakReference(service, true);
})();
GC.Collect();
GC.WaitForPendingFinalizers();
Assert.That(reference.Target, Is.Null, "reference should be null");
答案 0 :(得分:7)
Windsor仅在遇到退役问题时跟踪Transient
个实例。退役问题的典型示例是类实现IDisposable
接口。
因此,如果IThing
为Transient
并且未实施IDisposable
且,那么它没有任何其他解雇问题,那么Windsor将不会跟踪它和垃圾收集器可以/将删除IThing
的实例。
但(这是一个很大的但是),我建议你永远不要依赖这种行为。 IThing
可能会被开发人员更改,并且将来可能会变成一次性的。或者它可能会引起另一个退役问题。突然发生内存泄漏。因此,应该遵循一个简单的规则:
只要通过调用container.Resolve
明确解析对象,就必须通过调用container.Release
来释放它。此外,只要类型化工厂明确创建对象,就必须由类型化工厂明确销毁它。如果对象是暂时的,则无关紧要,请注意其生命周期。总是。对象的创建者(无论是windsor还是打字工厂)负责销毁对象。
基本上,@ piotrwest的评论是正确的。但是,这个答案旨在解释它不仅仅是IDisposable
- 它是关于退役的问题(IDisposable
只是其中之一)。
This great article解释了更多细节。