代码分析警告 CA2000:在对象“new ContainerControlledLifetimeManager()”上调用Dispose。

3

我的一些单元测试出现了代码分析警告:

WidgetManagerTests.cs (40): CA2000 : Microsoft.Reliability : 在方法 'WidgetManagerTests.TestInitialize()' 中, 在所有对它的引用超出作用域之前, 调用 System.IDisposable.Dispose 方法释放对象 'new ContainerControlledLifetimeManager()'。

我正在使用 Unity 和 Moq,以下是有问题的代码行:

var loggingServiceMock = new Mock<ILoggingService>();
            this.unityContainer.RegisterInstance<ILoggingService>(loggingServiceMock.Object, new ContainerControlledLifetimeManager());
1个回答

8
CA2000实现非常敏感,对于在可释放实例“移交”给另一个方法之前可能抛出异常的情况特别敏感。在这种情况下,即使容器最终会在注册过程中没有异常发生时负责清理生命周期管理器,但仍有可能在RegisterInstance调用之前或调用期间但在容器将生命周期管理器添加到自身内部状态之前发生异常。
为了解决这种可能性,您可以使用以下代码(尽管我个人不会在不需要执行任何重要操作的情况下这样做):
var loggingServiceMock = new Mock<ILoggingService>();

var lifetimeManager = new ContainerControlledLifetimeManager();
try
{
    this.unityContainer.RegisterInstance<ILoggingService>(loggingServiceMock.Object, lifetimeManager);
}
catch
{
    lifetimeManager.Dispose();
    throw;
}

谢谢,这个方法有效,虽然我使用了using语句使代码更简洁。 - Tom Robinson
5
将上述的 try/catch 语句替换为 using 语句将导致生命周期管理器被释放,即使没有异常。这似乎不会在没有抛出异常时产生您期望的行为。您已经测试了修改后代码的行为吗? - Nicole Calinoiu
1
@NicoleCalinoiu 这个怎么样:this.unityContainer.RegisterInstance<ILoggingService>(loggingServiceMock.Object, this.unityContainer.Resolve<ContainerControlledLifetimeManager>()); - Samuel
@Samuel:只有在你使用了 new 关键字创建可释放对象时,CA2000 规则才会触发。因此,使用任何方法来创建它(例如容器的 Resolve 方法)都将防止 CA2000 触发违规行为。 - Nicole Calinoiu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接