我正在使用实现IDisposable的第三方对象。为了使它能够进行单元测试"能够"我构建了一个包装器。我理解该对象实现了IDisposable,我的包装器也需要实现IDisposable。
public interface IWrapper : IDisposable
{
void Complete();
}
public class Wrapper : IWrapper
{
private readonly ThirdPartyLib lib;
public Wrapper()
{
lib = new ThirdPartyLib();
}
public void Complete()
{
lib.Comlete();
}
public void Dispose()
{
lib.Dispose();
}
}
public class Processor : IProcessor
{
private readonly IWrapper wrapper;
public Processor(IWrapper wrapper)
{
this.wrapper = wrapper;
}
public void Process()
{
// do some work
using (wrapper) {
// do more work
}
}
}
假设在一些使用它的类中注入了Processor并且执行了Process()
public class Wrapper : IWrapper { private ThirdPartyLib lib; public void Begin() { lib = new ThirdPartyLib(); } public void Complete() { lib.Comlete(); } public void Dispose() { lib.Dispose(); } }
然后使用它:
using (wrapper.Begin()) {
答案 0 :(得分:2)
你是对的。两次调用Process()
可能会导致异常。完全不调用Process()
会使对象不受干扰。
对于你应该做的事情没有简单的规则。有多个选项,可以使用哪些选项取决于代码中不在您问题中的其他部分。
如果Processor
引用了外部拥有的Wrapper
,则它根本不应该处置该包装。
如果Processor
在施工时获得Wrapper
的所有权,那么它应该在处置时处置该包装。这意味着Processor
也应该实现IDisposable
。
如果可以修改Processor
以按需创建新的Wrapper
,则可以在Process()
完成后处理该包装。
或者,正如您所建议的那样,如果可以修改Wrapper
以按需创建ThirdPartyLib
,那也可以。但要小心:调用wrapper.Begin(); wrapper.Begin();
会使一个ThirdPartyLib
不受约束且未引用。您需要更多地重新构建API以防止此问题成为问题,并且有效地说,这意味着将Wrapper
转换为ThirdPartyLibFactory
。
答案 1 :(得分:1)
我认为Processor
不应该处置IWrapper
,因为它不是实例化它的人,也不知道它是否可以被处置或者它是否被处置注入其他物体。在这种情况下,Processor
不应将using
与包装器一起使用。
处理IWrapper
的代码应该放在首先实例化它的类中,因为那是了解它的生命周期。