【问题标题】:constructor injection / dependency injection - dealing with 'root' classes构造函数注入/依赖注入 - 处理“根”类
【发布时间】:2013-01-30 14:31:34
【问题描述】:

我最近一直在使用大量依赖注入、测试驱动开发和单元测试,并且开始喜欢它。

我在类中使用构造函数依赖,这样我就可以注入模拟依赖以进行单元测试。

但是,当您真正想要生产环境中的对象时,最好的处理方法是什么?

你是否在任何你想创建类的地方都使用DependencyInjectionContainer.Get<MyClass>()?还是为类创建一个空白构造函数更有意义,它通过 DI 容器解决所有依赖关系?

【问题讨论】:

标签: dependency-injection inversion-of-control constructor-injection


【解决方案1】:

不需要有默认构造函数。

在您的生产代码中,您通常只需在应用程序中调用一次 DependencyInjectionContainer.Get(someRootType) 即可获取根类型(例如 MVC 中的 HomeController 类)。由于所有类型都是使用构造函数注入创建的,因此容器将能够为您创建相关对象的整个图。所以从生产的角度来看,没有必要拥有多个构造函数。

由于在您的单元测试中您通常希望注入所有模拟对象,因此您的测试也不会使用默认构造函数。另一方面,让每个测试直接调用被测类的构造函数很快就会导致代码难以维护,因为当构造函数发生更改时,您将不得不更改所有测试。相反,将该逻辑集中到测试类中的工厂方法中。这个工厂方法可以有多个重载,以方便测试创建被测类。

【讨论】:

  • 谢谢,我希望得到的解释 :) 但是,当您想“新建()”该项目时,您会怎么做,例如 var product = new Product();。你会做类似var product = DI.Get<Product>(); 的事情吗?
  • 实体是短暂的,通常不是由容器创建的。它们通常由IUnitOfWorkIRepository<T> 创建。
  • @KarlCassar:补充一下史蒂夫所说的:“服务”类型的对象由 DI 容器构造并连接在一起。服务对象可以创建“实体”对象。 DI 定义定义了哪个服务与哪个服务对话,服务本身通过传递实体相互对话。
  • 所以如果我有一个像Product 这样的实体,并且它有一个需要使用服务的方法,那么像DI.Get<ProductService>.GetRelatedProducts(this) 那样内联它是有意义的。请注意,这只是一个示例,而不是实际代码。
  • 调用实体方法的代码(我假设你应用了 DDD)是一个服务,并且会将其依赖项注入到它的构造函数中。您可以使用方法注入将这些依赖项传递给实体。我假设是这样的:void Handle(ProcessProductCommand command) { var product = this.repository.Get(command.ProductId); product.AssignValue(this.eventProcessor); }.
猜你喜欢
  • 1970-01-01
  • 2011-02-02
  • 1970-01-01
  • 1970-01-01
  • 2019-04-20
  • 2011-07-05
  • 2011-09-02
  • 2012-02-12
  • 2018-06-17
相关资源
最近更新 更多