【问题标题】:Code Analysis warning CA2000: Call Dispose on object 'new ContainerControlledLifetimeManager()'代码分析警告 CA2000:在对象“new ContainerControlledLifetimeManager()”上调用 Dispose
【发布时间】: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());

【问题讨论】:

    标签: unity-container code-analysis fxcop


    【解决方案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触发违规。
    猜你喜欢
    • 1970-01-01
    • 2016-04-07
    • 1970-01-01
    • 2011-03-31
    • 1970-01-01
    • 2011-06-22
    • 2018-07-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多