Castle Windsor Typed Factory 无释放不泄漏

Castle Windsor Typed Factory without release does not leak

我正在使用 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 I thought that a Transient object must be released by a Typed Factory method, otherwise the Typed Factory would keep a reference to the object. I tried to prove this by writing a test that used the method explained in this Whosebug article的理解。

但令我惊讶的是它实际上并没有失败,这意味着虽然我没有将瞬态对象释放回工厂,但它仍然可以被GC回收。我担心我的测试可能具有误导性,确实存在泄漏。

所以我的问题是:是我的 test 错了,还是 documentation 错了?

这是测试:

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");

Windsor 跟踪 Transient 个实例,仅当它们有一些退役问题时。退役问题的典型示例是 class 实现了 IDisposable 接口。

所以,如果 IThingTransient 并且它没有实现 IDisposable 那么它就没有任何其他退役问题Windsor 不会跟踪它,垃圾收集器 can/will 会删除 IThing.

的实例

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

任何时候通过调用 container.Resolve 显式解析对象时,都必须通过调用 container.Release 来释放它。同样,只要有类型的工厂显式创建对象,它就必须由有类型的工厂显式销毁。 对象是否为瞬态无关紧要,请注意其生命周期。总是。对象的创建者(无论是 windsor 还是类型工厂)负责对象的销毁。

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

This great article 解释更多细节。