代码之家  ›  专栏  ›  技术社区  ›  smvlad

如何确保对IDisposable对象调用Dispose方法,如果可能,如何将其集成到持续集成中?

  •  2
  • smvlad  · 技术社区  · 17 年前

    通常不调用Dispose表示可能出现错误或代码不完整,并可能导致一些难以发现的错误。理想情况下,我想指出在单元测试期间是否没有调用Disposed。

    我们使用的方法之一是将Debug.Assert放在终结器中

    #if DEBUG
    ~MyClass()
    {
        Debug.Assert(false, “MyClass.Dispose() was not called”);
    }
    #endif
    

    我们发现自己点击了assert消息框,但它在忽略弹出窗口的持续集成构建中效果不佳。

    3 回复  |  直到 17 年前
        1
  •  3
  •   David M    17 年前

    如果您以某种方式记录此日志,而不是使用Debug.Assert,并使用依赖项注入来指定记录器实现,那么您可以使用模拟测试来捕获此日志。所以

    public MyClass : IDisposable
    {
    
    IEventLogger _eventLogger;
    
    public MyClass() : this(EventLogger.CreateDefaultInstance())
    {
    }
    
    public MyClass(IEventLogger eventLogger)
    {
        _eventLogger = eventLogger;
    }
    
    // IDisposable stuff...
    
    #if DEBUG
    ~MyClass()
    {
        _eventLogger.LogError("MyClass.Dispose() was not called");
    }
    #endif
    
    }
    
        2
  •  0
  •   Jason Coyne    17 年前

    可以编写fxCop规则来检测此问题。

    另外,确保IDisposable的所有用法都在using{}块中使用,这使得处理起来更加容易。

    我检查的规则是手动调用Dispose()还是使用{}

    当然,在所有情况下,手动调用dispose都很难检测到,因为可能存在阻止调用发生的流控制或异常。

        3
  •  0
  •   Michael Larionov    17 年前

    您可以使用模拟对象框架(如Rhinomock)确保调用IDisposable.Dispose()。如果未调用Dispose(),框架将自动使生成失败。