在使用依赖注入时注入新对象VS注入现有对象?

时间:2015-05-07 11:43:02

标签: .net dependency-injection

  1. 当使用依赖注入时,类用户如何理解构造函数何时需要对象的新实例?何时不是?
  2. 例如,类Car需要一个实现IEngine接口的类的新实例。

    public class Car
        public sub new(Engine as IEngine)
        end sub
    end class
    

    同时,类Messager不需要实现ILogger接口的类的新实例。

    public class Messager
        public sub new(Logger as ILogger)
        end sub
    end class
    
    1. 开发人员或用户如何最大限度地降低滥用风险?

1 个答案:

答案 0 :(得分:1)

  

使用依赖注入时,类用户如何理解   构造函数需要一个对象的新实例,何时不需要?

如果类需要其依赖项的新实例,那么您将破坏Dependency Inversion Principle,因为您正在将实现细节泄漏到使用类中。这堂课不应该知道也不应该关心这个。

在运行时,您可能会构建一个无法重复使用的特殊引擎类型,但它可以由Composition Root来了解这一点;消费者不应该在乎。

您遇到的问题可能是将带有运行时数据的对象注入服务中引起的。通过依赖注入,您可以构建组件的对象图(具有行为的类),并通过方法调用传递此对象图的数据对象(如消息,DTO,实体等)。无论何时通过将状态(即运行时数据)注入组件的构造函数来破坏此规则,您都会遇到麻烦。

然而,常见的错误来源是名为Captive Dependencies的问题。强制依赖是一种依赖,它被配置为具有比其消费类型更短的生命周期。例如,您的Car可以注册为单身,而IEngine则是短暂的。在这种情况下,Car会使IEngine保持活动的时间长于预期。

有几种方法可以防止这种情况发生。

例如,在手动构建对象图时,您经常会发现这些错误很容易弹出;但不幸的是并非总是如此。

如果你使用DI库,一些库(Simple Injector和Castle Windsor)包含诊断工具,警告你这样的错误。

防止这种情况的另一个好方法是防止您的组件保持任何状态。这允许您使这个完整的对象图由单例组成,这将防止首先陷入此问题。这并不意味着您不能拥有生活方式较短的对象(例如工作单元),但您只需要防止这些对象被注入对象图中组件的构造函数中