【问题标题】:Does injecting a generic interface with concrete types defeat the purpose of dependency injection?注入具有具体类型的通用接口是否会破坏依赖注入的目的?
【发布时间】:2016-10-06 00:12:32
【问题描述】:

考虑以下场景。

public interface IRestaurant<IDinner, IDesert> { }

public class Pasta : IDinner {}
public class Cake : IDesert {}

public class Chef 
{
    // resolving a mix of interfaces and concrete classes
    public Chef(IRestaurant<Pasta, Cake>) { }
}

注入两个具体类是否违背了依赖注入的目的?我的感觉是确实如此,因为我们现在与PastaCake 类强耦合,而依赖注入可以打破这种耦合。

以下内容会更有意义吗?

public class Chef<IDinner, IDesert>
{
    public Chef(IRestaurant<IDinner, IDesert>) { }
}

【问题讨论】:

  • 除了意大利面和蛋糕外,厨师可以做一顿有晚餐和甜点的饭吗?
  • 在第一个例子中,没有,在第二个例子中,是的。
  • 我想这归结为意图,如果厨师只能处理这种组合,那么使用具体类型似乎很好。如果他们可以处理比这更多的组合,那么泛型会更合适。也许如果你把它写成public class PastaAndCakeChef,意图会更明显?
  • 我不认为注入混凝土本身总是一件坏事,但如果你打算创造一些通用的东西,第二种方法是最好的
  • 您正在使用依赖注入来确保为您提供合适的餐厅,我猜有哪个餐厅供应意大利面和蛋糕?依赖注入的重点实际上是管理生命周期和实现选择。如果您可以在对象之外控制实现选择,那么解耦会变得更容易,但它不是 DI 的唯一点。

标签: c# generics dependency-injection interface


【解决方案1】:

我认为您在这里混合了概念-无论您使用接口还是具体类本身,DI 本质上都没有任何关系。您可以(例如)注入一个具体类,它是 Pasta 的几个子类之一(LinguiniRavioli 等),并且 DI(低耦合、离散可测试性)的好处仍然适用。

大多数人使用接口,因为这进一步降低了与您需要的特定接口的耦合,而不暗示任何实现(例如,可能让 GlutenFreeElbowNoodles 继承自 Pasta 没有意义)但那不是不是真正的 IoC 问题。

【讨论】:

  • 当然。可以说,依赖注入甚至适用于纯函数式语言,甚至没有类。 DI 只是实现选择与合同(使用)的分离。希望这会激励人们构建更适合独立测试的实现。
  • 似乎没有接口/继承的依赖注入允许我们从依赖类外部更改依赖项的构造函数的参数。使用接口/继承,我们还可以从类外部更改依赖项的实现。是对的吗? (抱歉删除我之前的评论)。
  • 不用担心。我不确定你到底在问什么,但一般的 DI 模式(至少在 Java/C# 中)是传递给构造函数的任何内容都是 required 依赖项,并且任何设置为属性的内容( Java 中的 getter/setter)是一个可选的依赖项(可以设置,但没有它类也可以工作)。同样,并非特定于 DI - 您当然可以通过普通代码更改您使用的实现,DI 只是为您提供了一种标准、一致的方式。
  • 我要问的是这句话是否属实:“依赖注入在没有继承的语言中很有价值,在具有继承的语言中变得更强大。”
  • 好的——你没有问继承你问的是接口。这些是不同的东西。我不认为 DI 在没有继承的语言中占有一席之地,除非您谈论的是一种纯函数式语言,您可以在其中注入具有给定签名的任何方法。
猜你喜欢
  • 2023-04-06
  • 1970-01-01
  • 2021-04-24
  • 2015-08-30
  • 2014-10-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-18
相关资源
最近更新 更多