【问题标题】:Castle Windsor Typed Factory without release does not leakCastle Windsor Typed Factory 不发布不泄露
【发布时间】:2016-10-28 15:02:15
【问题描述】:

我正在使用 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 的理解,我认为瞬态对象必须由类型化工厂方法释放,否则类型化工厂将保留对该对象的引用。我试图通过编写一个使用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");

【问题讨论】:

  • 有什么问题?
  • 您的“ITing”是否扩展/实现了 IDisposable 接口?上面写着“Windsor 总是跟踪通过类型化工厂解析的一次性非单件组件。”。
  • 我认为 piotrwest 已经回答了我的问题:不,我的 IThing 没有实现 IDisposable。我错过了“Windsor 总是跟踪 disposable...”的含义。谢谢!

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


【解决方案1】:

Windsor 仅在 Transient 实例存在一些退役问题时才对其进行跟踪。退役问题的一个典型例子是一个类实现了IDisposable 接口。

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

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

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

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

This great article 解释更多细节。

【讨论】:

  • 很好的解释!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多