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

C# 如何确保对IDisposable对象调用Dispose方法,如果可能,如何将其集成到持续集成中?,c#,unit-testing,C#,Unit Testing,通常不调用Dispose表示可能出现错误或代码不完整,并可能导致一些难以发现的错误。理想情况下,我想指出在单元测试期间是否没有调用Disposed 我们使用的方法之一是将Debug.Assert放在终结器中 #if DEBUG ~MyClass() { Debug.Assert(false, “MyClass.Dispose() was not called”); } #endif 我们发现自己点击了assert消息框,但它在忽略弹出窗口的持续集成构建中不起作用。如果您以某种方式记录这

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

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

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

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

如果您以某种方式记录这一点,而不是使用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

}

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

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

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


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

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

btw。您可以使用Debug.fail(…)而不是Debug.Assert(false,…)