没有释放的Castle Windsor Typed Factory不会泄漏

时间:2016-10-28 15:02:16

标签: c# inversion-of-control castle-windsor

我正在使用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");

1 个答案:

答案 0 :(得分:7)

Windsor仅在遇到退役问题时跟踪Transient个实例。退役问题的典型示例是类实现IDisposable接口。

因此,如果IThingTransient并且未实施IDisposable ,那么它没有任何其他解雇问题,那么Windsor将不会跟踪它和垃圾收集器可以/将删除IThing的实例。

但(这是一个很大的但是),我建议你永远不要依赖这种行为。 IThing可能会被开发人员更改,并且将来可能会变成一次性的。或者它可能会引起另一个退役问题。突然发生内存泄漏。因此,应该遵循一个简单的规则:

只要通过调用container.Resolve明确解析对象,就必须通过调用container.Release来释放它。此外,只要类型化工厂明确创建对象,就必须由类型化工厂明确销毁它。如果对象是暂时的,则无关紧要,请注意其生命周期。总是。对象的创建者(无论是windsor还是打字工厂)负责销毁对象。

基本上,@ piotrwest的评论是正确的。但是,这个答案旨在解释它不仅仅是IDisposable - 它是关于退役的问题(IDisposable只是其中之一)。

This great article解释了更多细节。