防止Autofac持有一次性实例

时间:2018-01-09 06:29:16

标签: c# memory-leaks autofac

我遇到了Autofac创建内存泄漏的问题。 经过一番调查后,我得出结论,内存泄漏是Autofac持有一次性实例的结果。 因此有两种方法可以解决这种情况: 1.处理范围 2.在解析/注册时使用Owned<> / ExternalyOwned()语法。

首先我们不使用(除了非常具体的小子案例)范围之外的问题,所有注册和解决都是在单一的“全局”范围内完成的,这种范围从未被处理过。我们不想使用定位器反模式,所以基本上我们有一个顶级“解析”就是这样,所以范围不是那里的选项。

第二个问题(我现在选择作为临时解决方案)是我们希望我们的代码尽可能是通用IOC,而不是与Autofac绑定,因此拥有构造函数中的Owned不是一个选项(毕竟我们使用Autofac的主要原因不仅仅是IOC,而且还可以通过FakeItEasy或Mock对没有Autofac的单元测试类进行单元测试,这种力可以将.ExternallyOwned()放在可以创建为瞬态的一次性类的每个注册上(.InstancePerDependency) ()或默认)。由于这变得非常难以跟踪,类和它们的用法可以改变,这基本上意味着我在每次注册时都放了.ExternallyOwned(),这很好,但是很不方便。

所以我的问题是 - 有没有办法全局禁用此功能(基本上每个类都注册,默认注册为.ExternallyOwned())? 或者也许是否有另一种解决方案来解决这个问题?

谢谢。

1 个答案:

答案 0 :(得分:1)

从技术上讲,Autofac不会导致内存泄漏。这是Autofac的错误用法。创建范围并处理它们是唯一真正的解决方案(尽管可能需要做很多工作)。

如果您想使用ExternallyOwned,您可以考虑通过创建一个可以为您完成的扩展方法来使其更容易。在所有文件中使用简单的查找+替换,您可以使用新方法。

public static IRegistrationBuilder<TImplementer, ConcreteReflectionActivatorData, SingleRegistrationStyle> 
    RegisterTypeAsExternallyOwned<TImplementer>(this ContainerBuilder builder)
{
    return builder.RegisterType<TImplementer>().ExternallyOwned();
}

我在浏览器中写这个,所以我不完全确定它是如何编译的。但这是我能想到的唯一选择。

小心ExternallyOwned。它会阻止Autofac保持对这些对象的引用,但它确实意味着你必须自己处理这些实例。