【问题标题】:Does the use of Dependency Injection necessitate the use of Interfaces to be injected rather than concrete classes?使用依赖注入是否需要使用要注入的接口而不是具体的类?
【发布时间】:2013-06-25 18:07:29
【问题描述】:

我听说一位开发人员在工作中提到 DI 的重点应该是使用接口。作为经验法则,应将具体类的使用保持在最低限度。如果我们将 DI 配置为使用特定类的实例不止少数,那么它就是代码异味。

现在我不确定是否可以将此作为一条空白规则。我一直认为 DI 的一个重要原因是易于测试。

可能有其他原因使用接口,而不是具体类作为我的代码中的依赖项(比如易于插入逻辑的其他实现等),但我看不出依赖注入的使用意味着什么那个。

编辑:假设我有一个类 BookingMapper,它将 Booking 对象从一个域映射到另一个域。假设它有一个 Hotel 对象,它需要作为映射 Booking 的一部分进行映射。它使用 HotelMapper 类来做同样的事情。

public class Booking
{
    ...
    Hotel Hotel;
}

public class BookingMapper
{
    private readonly HotelMapper hotelMapper;
    public BookingMapper(HotelMapper hotelMapper)
     {
      this.hotelMapper = hotelMapper;
     }
    Map(){...}
}
public class HotelMapper
{
     Map(){...}
}

在这样的用例中,我已经知道我的 Booking Mapper 组件在任何时候都将与我的 HotelMapper 处于同一级别,并且由于单一责任原则enter link description here 而被分离出来。提取出像

这样的接口对我来说仍然有意义吗
public interface IHotelMapper
{
void Map();
}
public class BookingMapper
    {
        private readonly IHotelMapper hotelMapper;
        public BookingMapper(IHotelMapper hotelMapper)
         {
          this.hotelMapper = hotelMapper;
         }
        Map(){...}
    }

然后将其用作 BookingMapper 中的依赖项而不是直接使用 HotelMapper ?

【问题讨论】:

  • 这个网站上已经有一些很好的答案。 Dependency injection with interfaces or classes 很好地解释了为什么接口虽然严格来说不是必需的,但确实很有意义。
  • 我们主要解决了为什么在接口和具体类之间创建 1-1 关系是一个问题(例如在接口中的中断更改)。虽然,在这里我宁愿试图理解为什么总是创建这些 1-1 关系(如果有的话)是一个硬性规定,我什么时候可以跳过这样做。
  • 感谢您的链接,但我们主要讨论的是在该帖子中使用接口而不是实例的问题。我很想知道使用界面本身的动机到底是什么。我可以从该页面下车的最接近的答案是“我会坚持使用接口。它们被设计为外部实体的消费合同。”虽然我同意使用接口的一般想法,但我不确定是否可以将其应用于我使用 DI 的每个场景。

标签: c# dependency-injection


【解决方案1】:

看看SOLIDprinciples,然后再看看它们。您会看到 DI 和基于接口的设计是 OOP 的重要组成部分。它认为你会同意你的同事说得很有道理。是的,你是对的,DI 会让你的测试更容易/更好。

http://en.wikipedia.org/wiki/SOLID_(object-oriented_design)

【讨论】:

  • 谢谢,读得很好。准确地说,这里适用的原则是依赖倒置原则。但是话又说回来……用例谈到了依赖于低级组件的高级组件。如果我考虑到我依赖于同一级别的组件的情况(例如 Mapper 类或工厂),我仍然觉得这种情况可能是这条规则的例外吗?你不觉得
  • @noobMama... 会有例外吗?是的,这就是 Unity 等 DI 容器为实例提供功能的原因。就个人而言,我几乎只将接口用于 DI,但也使用过实例。
  • 嗯..,所以总而言之,我将在实例上使用接口更多地作为指导,而不是硬性规定。
  • 你应该首先考虑界面。这应该是你的规则。仅适用于边缘情况。你的代码会更好。
【解决方案2】:

依赖注入是一种无需定义接口就可以完全使用的模式。您可以让消费者依赖于其他具体类。通过将这些类的重要方法设为虚拟,您甚至可以从中派生出虚假的实现以用于测试目的。

但是depending on abstractions instead of implementations:

  • 测试变得更加容易和安全,因为您不会拖后腿。
  • 您的应用程序的各个部分可以单独部署,因为消费者只依赖于抽象,而不是实现。
  • 在处理接口时,使用decorator pattern(或使用其他AOP 技术,如interception)附加行为要容易得多。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-25
    • 2023-04-06
    • 1970-01-01
    • 1970-01-01
    • 2010-12-29
    • 2021-02-24
    • 1970-01-01
    相关资源
    最近更新 更多