【发布时间】:2016-12-16 16:46:00
【问题描述】:
我正在使用实现 IDisposable 的第 3 方对象。为了使其单元测试“能够”,我构建了一个包装器。我知道对象实现了 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
}
}
}
假设处理器被注入到某个正在使用它的类中并执行 Process()
- 如果我们再次调用 Process(),包装器会发生什么情况? - ThirdPartyLib() 不会抛出异常,因为它只创建一次(在包装器构造函数中),现在它已被释放
- 只要有对它的引用,它就不会被释放吗?
- 是否应该以这样的方式构建包装器:ThirdPartyLib 的 new()“ing”不是在构造函数中而是在单独的方法中执行,比如 Begin() - 像这样:
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()) {
【问题讨论】:
-
我觉得我们对此没有大局观。为什么
Processor只处理一个注入构造函数的Wrapper?通常我希望你是Processor会有一个像Process(IWrapper wrapper)这样的方法调用,允许你处理那个包装器,但我还是在营地里,调用者必须调用'Dispose'IWrapper因为它实际上拥有它。如果不是这种情况,那么我可能会在IProcessor上实现IDisposable,并且仅在处理时处理IWrapper。 -
在 IProcessor 上实现 IDisposable 是否只会在 IProcessor 被释放时释放 Wrapper(在当前设计中),而不是在 using 语句的“}”被命中时释放 Wrapper?这是因为(父) IProcessor 持有对 IWrapper 的引用 - 即使我们告诉它在“}”上进行处理
-
这就是为什么用 DI 初始化的对象应该假设它们拥有注入的对象。大多数情况下,它们是其他对象使用的单例,或者至少有其他东西在控制生命周期。依赖于 DI 的对象应该只使用该对象并假设。无论创建了传入对象的什么,也应负责稍后对其进行核对。 DI就像“嘿,我只想要一个对象,其他人可以为我创建和删除它”
-
"只要有对它的引用,它就不会被处理掉吗?" -- 我认为一旦不再有对对象的任何强引用,那么它就可以用于垃圾收集。 GC 调用对象的finalizer,GC 不会寻找 Dispose() 并调用它。由于没有更多引用而被垃圾收集的对象与该对象的 Dispose() 方法无关;它们仅在为显式调用 Dispose 的对象实现终结器时才相关。在您的代码中,该对象仅在 您 调用 Dispose 时“被释放”,这是您在
using语句中所做的。 -
“只要有对它的引用,它就不会被释放吗?” - 如果你调用
Dispose(),那么有问题的对象会 i> 无论引用计数如何,都会遭到攻击。