当尝试正确使用依赖注入和 IDisposable 接口时,我应该注入一个 SafeHandle 实例吗? C#

When trying to use dependency injection and the IDisposable interface correctly should I inject an instance of SafeHandle? C#

根据 MSDN,实现 IDisposable 接口的最佳方法涉及使用 SafeHandle 的实例 class。

given example 中有以下行;

SafeHandle handle = new SafeFileHandle(IntPtr.Zero, true);

我一直在阅读依赖注入和 TDD,我的理解是,为了遵循 TDD 并正确实现 IDisposable 接口,我会做这样的事情;

public class SomeDisposableClass : IDisposable
{
    private readonly Stream _stream;
    private readonly IDisposable _safeHandle;

    public SomeDisposableClass(Stream stream, IDisposable safeHandle)
    {
        _stream = stream;
        _safeHandle = safeHandle;
    }

    private bool disposed = false;

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (disposed) return;

        if (disposing)
        {
            _safeHandle.Dispose();
            _stream.Dispose();
        }

        disposed = true;
    }
}

我正在注入我的 safeHandle,而不是在 SomeDisposableClass 中实例化它。这将允许我传入模拟并断言在 SomeDisposableClass 实例调用其 Dispose() 方法的情况下调用其 Dispose 方法。

在使用 TDD 和依赖注入时,这是正确的做法吗?还是我做得太过火了? (即可以实例化某些 classes 而不是注入它们,还是我应该像瘟疫一样避免 "new"?)

我知道我的示例存在问题(例如,您不必传入 SafeHandle 实例,只需传入 IDisposable 实例)。

您不应使用 DI 为您的 class 提供 SafeHandleSafeHandle 是您的 class 中的内部实现细节,它用于实现 IDisposable。 class 的用户不必了解此内部实现。 DI 旨在为您的 class 提供与您的 class 协作的外部实体。不要害怕对仅在 class.

中使用的对象使用 new

这本书是一个非常好的资源:http://www.growing-object-oriented-software.com/我不能在这里描述整本书,但这里有一些想法。他们谈论 "values" 和 "objects"。

Values are immutable instances that model fixed quantities. Objects ... use mutable state to model their behavior over time.

本书中描述的样式使用 DI 连接相互协作的 "objects" 网络,并使用模拟对象来测试这些协作。另一方面,"values" 是在生产和测试代码中需要时使用 new 创建的,并作为参数和 return 值传递。