c# - 如果接口(interface)调用 Dispose 的实现是否是泄漏抽象

标签 c# .net design-patterns dependency-injection loose-coupling

考虑这段代码:

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

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

我们现在想重构它以松耦合。我们最终得到这个:

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);       
  }
}

看起来不错吧?现在任何实现都可以使用该接口(interface),一切都很好。

如果我现在说实现是一个 WCF 类,并且重构完成之前的 using 语句是有原因的,那会怎样呢?即/关闭 WCF 连接。

所以现在我们的接口(interface)必须实现 Dispose 方法调用,或者我们使用工厂接口(interface)来获取实现并围绕它放置一个 using 语句。

对我来说(虽然对这个主题很陌生)这似乎是一个有漏洞的抽象。为了实现处理内容的方式,我们不得不在我们的代码中放置方法调用。

谁能帮助我理解这一点并确认我是对还是错。

谢谢

最佳答案

是的,当您让 ICustomerCreditService 实现 IDisposable 时,这是一个有漏洞的抽象,因为您现在已经编写了带有特定实现的 ICustomerCreditService头脑。此外,这向该接口(interface)的消费者传达了它可以处置该服务的信息,这可能是不正确的,特别是因为一般来说,资源应该由创建它的人(拥有所有权)来处置。当您将资源注入(inject)到类中时(例如使用构造函数注入(inject)),并不清楚消费者是否获得了所有权。

因此,一般来说,负责创建该资源的人应该处置它。

但是,在您的情况下,您甚至可以通过实现 ICustomerCreditServiceClient 的非一次性实现来简单地防止这种情况发生,该实现只需在同一方法调用中创建和配置 WCF 客户端。这使一切变得容易得多:

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

关于c# - 如果接口(interface)调用 Dispose 的实现是否是泄漏抽象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12259534/

相关文章:

c# - Devexpress 或 Telerik Controls 比较

.net - 导航框架的转换内容控制(WCF RIA 服务)

.net - 创建将字符串转换为可为空的数字的通用方法

java - 如何使这部分代码可扩展,

asp.net-mvc - ASP.net MVC : IS this pattern reasonable or conceptually incorrect?

php - 解释这个单例工厂模式

c# - 单击桌面快捷方式时从系统托盘恢复应用程序

c# - 如何访问 ThisAddin.cs 文件中的方法

c# - 将 PaperKind 转换为 PageMediaSizeName

.net - 我们不应该在 WinForms 应用程序中使用 System.Web.Caching.Cache 类吗?