【问题标题】:What should be injected as C'tor paramter under DI principles?在 DI 原则下应该注入什么作为 Ctor 参数?
【发布时间】:2010-07-29 11:24:38
【问题描述】:

我试图了解哪些对象应该注入到一个对象中,哪些应该在内部创建。

  1. 如果我有一些List<int>(作为数据字段)保存在运行时收集的信息。看来我应该在 c'tor 中初始化它而不是注入它。

但是通过 COM 端口进行通信的硬件类呢?

我是让硬件类初始化 SerialPort 还是注入它?

  1. 如果上面提到的SerialPort需要注入;最好的方法是什么?

我是否手动创建它:

SerialPort port = new SerialPort(name, baud ...);

HWClass hwClass = container.Reolve<IHWClass>("HWClass", new InjectionConstructor(port));

或使用 Unity 容器

SerialPort port = conatiner.Resolve<SerialPort>(...);

HWClass hwClass = container.Reolve<IHWClass>("HWClass", new InjectionConstructor(port));

还是应该在 HWClass C'tor 中初始化它?

阿迪尔

【问题讨论】:

    标签: c# dependency-injection unity-container ioc-container


    【解决方案1】:

    Domain-Driven Design 区分 Services 和其他域对象(EntitiesValue Objects)。即使您不订阅 DDD,这种区别也非常有用。

    服务通常是为消费者执行操作的长期无状态对象。它们是典型的依赖项,您可以从注入中受益匪浅。

    在您的情况下,SerialPort 和 IHwClass 听起来都非常像服务,因为它们代表外部资源,所以我会肯定会通过 Constructor Injection 注入它们

    但是,只有注入抽象才能真正获得松散耦合的好处。 IHWClass 看起来不错,因为它是一个接口,但 SerialPort 看起来像一个具体的类,因此注入它并不会获得太多收益。 从 SerialPort(例如 ISerialPort)中提取接口并注入它会更好。

    【讨论】:

    • 或者,例如,如果 SerialPort 继承或充当流,则改为使用 Stream 作为接口。
    • 谢谢。实际上,我指的是 .net FW 的 System.IO.Ports.SerialPort,这是一个非常具体的类。仅仅为了注入目的而用接口包装它似乎很人为,不是吗?这听起来像“如果无法提取接口 - 不要注入!”我错了吗 ?使用 Unity 创建 SerialPort 有什么好处,或者在这种情况下与我自己创建它一样吗?
    • 包装现有的 API 是很正常的:stackoverflow.com/questions/3264992/… 如果接口已经到位当然会更容易,但这样做还是值得的。
    【解决方案2】:

    我的一般规则是,如果对象可以从您的类外部更改其状态,或者您希望能够在测试中或将来动态地提供替代实现,您应该注入它。如果该类仅在内部使用和修改,并且实现仅依赖于包含的类,那么在内部创建依赖关系可能是可以的。使用您的示例,我会注入 SerialPort,但不会注入 List&lt;int&gt;

    顺便说一句,现在我做 TDD(测试驱动开发),我发现我真的不太担心这些决定。您很快就会知道需要注入哪些类才能解耦您的类以使测试更容易。即使您一开始没有做对,但在几次测试中,您会发现您的代码自然而然地朝着这个方向发展。

    【讨论】:

      猜你喜欢
      • 2018-03-01
      • 1970-01-01
      • 2020-09-20
      • 1970-01-01
      • 1970-01-01
      • 2016-03-30
      • 1970-01-01
      • 1970-01-01
      • 2023-03-24
      相关资源
      最近更新 更多