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

Posted

技术标签:

【中文标题】代码分析警告 CA2000:在对象“new ContainerControlledLifetimeManager()”上调用 Dispose【英文标题】:Code Analysis warning CA2000: Call Dispose on object 'new ContainerControlledLifetimeManager()' 【发布时间】:2010-07-15 13:45:16 【问题描述】:

我的一些单元测试收到代码分析警告:

WidgetManagerTests.cs (40): CA2000 : Microsoft.Reliability:方法中 'WidgetManagerTests.TestInitialize()', 调用 System.IDisposable.Dispose 对象'新 ContainerControlledLifetimeManager()' 在所有对它的引用都没有之前 范围。

我正在使用 Unity 和 Moq,这是违规行:

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

【问题讨论】:

【参考方案1】:

CA2000 实现对在一次性实例“移交”给另一个方法之前可能引发异常的情况非常敏感。在这种情况下,即使在注册过程中没有发生异常时容器最终会清理生命周期管理器,也有可能在 RegisterInstance 调用之前或在调用中但在容器将生命周期管理器添加到它之前发生异常。自己的内部状态。

为了解决这种可能性,您可以使用如下代码(尽管我自己可能不会为此烦恼,除非处置做了重要的事情):

var loggingServiceMock = new Mock<ILoggingService>();

var lifetimeManager = new ContainerControlledLifetimeManager();
try

    this.unityContainer.RegisterInstance<ILoggingService>(loggingServiceMock.Object, lifetimeManager);

catch

    lifetimeManager.Dispose();
    throw;

【讨论】:

谢谢,虽然我使用了 using 语句使代码更简单,但这仍然有效。 使用 using 语句代替上述 try/catch 将导致生命周期管理器被释放,即使没有异常也是如此。当没有抛出异常时,这可能不会导致您期望的行为。修改后代码的行为你测试了吗? @NicoleCalinoiu 怎么样:this.unityContainer.RegisterInstance(loggingServiceMock.Object, this.unityContainer.Resolve()); @Samuel:CA2000 规则只有在您 newed 一次性使用时才会触发,因此使用任何方法来创建它(例如容器的 Resolve 方法)都会阻止 CA2000触发违规。

以上是关于代码分析警告 CA2000:在对象“new ContainerControlledLifetimeManager()”上调用 Dispose的主要内容,如果未能解决你的问题,请参考以下文章

代码分析:TableCell如何攻克CA2000

静态代码分析警告 CA2104 都有哪些安全问题?

代码分析规则 CA2000 / CA2202

CA2000:Microsoft.Reliability 对象未沿所有异常路径进行处理

分析 FxCop / 代码分析警告 CA1506: AvoidExcessiveClassCoupling

名为 MultiString 的类的 Visual Studio 2010 代码分析警告 CA1704