我用的是温莎城堡类型的工厂。在我们的注册代码中,它被设置为可以创建一个临时组件:
container.AddFacility<TypedFactoryFacility>();
container.Register(Component.For<IThingFactory>().AsFactory());
container.Register(Component.For<IThing>().ImplementedBy<TransientObject>().Named("TransientObject").LifeStyle.Transient);根据我对温莎城堡类型的工厂文档的理解,我认为临时对象必须由类型化工厂方法释放,否则类型化工厂将保留对对象的引用。我试图通过编写一个使用这篇StackOverflow文章中解释的方法的测试来证明这一点。
但令我惊讶的是,它并没有真的失败,这意味着,虽然我还没有将瞬态对象释放回工厂,它仍然可以由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");发布于 2017-04-07 07:05:08
只有当Transient实例有一些退役问题时,温莎才会跟踪它们。退役关注点的一个典型例子是类实现了IDisposable接口。
因此,如果IThing是Transient,并且没有实现IDisposable 和,那么温莎就不会跟踪它,垃圾收集器可以/将删除IThing的实例。
但是(这是一个很大的但是),我建议您永远不要依赖这种行为。IThing可能会被开发人员改变,将来可能会变成一次性的。或者它可能会引起另一个退役的担忧。突然发生了记忆泄漏。因此,应遵循一条简单的规则:
当一个对象通过调用container.Resolve container.Release**.显式解析时,必须通过调用来释放。而且,当一个对象显式地由一个类型化工厂创建时,它必须被类型化工厂显式地销毁。**不管对象是否是临时的,请注意它的生命周期。一直都是。对象的创建者(无论是温莎还是类型化工厂)负责销毁该对象。
基本上,@piotrwest的评论是对的。然而,这个答案的目的是要解释,它不仅仅是关于IDisposable的--它是关于退役问题的(IDisposable只是其中之一)。
这篇伟大的文章解释了更多细节。
https://stackoverflow.com/questions/40307887
复制相似问题