它是一个漏水的抽象,如果实现的接口调用Dispose [英] Is it a leaky abstraction if implementation of interface calls Dispose

查看:109
本文介绍了它是一个漏水的抽象,如果实现的接口调用Dispose的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑这个code:

public class MyClass()
{
  public MyClass()
  {    
  }

  public DoSomething()
  {
    using (var service = new CustomerCreditServiceClient())
    {
       var creditLimit = service.GetCreditLimit(
         customer.Firstname, customer.Surname, customer.DateOfBirth);       
    }
  }
}

我们现在要重构它以松散耦合的。我们结束了这一点:

We now want to refactor it to loosely couple it. We end up with this:

public class MyClass()
{
  private readonly ICustomerCreditService service;

  public MyClass(ICustomerCreditService service)
  {
     this.service= service;
  }

  public DoSomething()
  {
     var creditLimit = service.GetCreditLimit(
       customer.Firstname, customer.Surname, customer.DateOfBirth);       
  }
}

看起来不错吧?现在,任何实现可以使用的界面,一切都很好。

Looks ok right? Now any implementation can use the interface and all is good.

如果我现在说,执行是一个WCF类和using语句重构之前做是有原因的。 IE /关闭WCF连接。

What if I now say that the implementation is a WCF class and that the using statement before the refactoring was done was there for a reason. ie/to close the WCF connection.

所以,现在我们的接口必须实现处置方法调用,或者我们用一个工厂接口来获得实施,并把using语句解决这一问题。

So now our interface has to implement a Dispose method call or we use a factory interface to get the implementation and put a using statement around that.

要我(虽然新的主题),这似乎是一个漏水的抽象。我们不得不把方法调用我们的code只是为了执行正在处理的东西的方式。

To me (although new to the subject) this seems like a leaky abstraction. We are having to put method calls in our code just for the sake of the way the implementation is handling stuff.

有人能帮助我理解这一点,并确认我是否正确或错误。

Could someone help me understand this and confirm whether I'm right or wrong.

感谢

推荐答案

是的,这是一个漏水的抽象,当你让 ICustomerCreditService 实施 IDisposable的,因为你现在已经写 ICustomerCreditService 用一记具体实施。进一步,这个通信以它可以处置该服务,这可能是不正确的,特别是因为在一般情况下,一个资源应设置在由谁创建它的酮(谁拥有所有权),该界面的消费者。当你注入一个资源到一个类(使用构造函数注入的实例),目前尚不清楚,如果消费者给出的所有权。

Yes, it is a leaky abstraction when you let ICustomerCreditService implement IDisposable, since you've now written ICustomerCreditService with a specific implementation in mind. Further more, this communicates to the consumer of that interface that it could dispose that service, which might not be correct, especially since in general, a resource should be disposed by the one who creates it (who has the ownership). When you inject a resource into a class (using constructor injection for instance), it is not clear if the consumer is given the ownership.

所以一般来说一个负责创建资源应该处理它。

So in general the one responsible of creating that resource should dispose it.

不过,你的情况,你可以简单地prevent这甚至从发生通过实施非一次性实施 ICustomerCreditServiceClient ,简单地创建和部署WCF客户端在同一个方法调用。这使得一切都变得容易多了。

However, in your case, you can simply prevent this from even happening by implementing a non-disposable implementation of ICustomerCreditServiceClient that simply creates and disposes the WCF client within the same method call. This makes everything much easier:

public class WcfCustomerCreditServiceClient
    : ICustomerCreditServiceClient
{
    public CreditLimit GetCreditLimit(Customer customer)
    {
        using (var service = new CustomerCreditServiceClient())
        {
            return service.GetCreditLimit(customer.Firstname,
                customer.Surname, customer.DateOfBirth);       
        }
    }
}

这篇关于它是一个漏水的抽象,如果实现的接口调用Dispose的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆