【发布时间】:2011-10-07 16:48:30
【问题描述】:
在少数情况下,我通常很想使用“混蛋注入”。当我有一个“正确的”依赖注入构造函数时:
public class ThingMaker {
...
public ThingMaker(IThingSource source){
_source = source;
}
但是,对于我打算作为 公共 API 的类(其他开发团队将使用的类),我再也找不到比编写一个默认的“混蛋”构造函数更好的选择了- 可能需要的依赖:
public ThingMaker() : this(new DefaultThingSource()) {}
...
}
这里明显的缺点是这会创建对 DefaultThingSource 的静态依赖;理想情况下,不会有这样的依赖,消费者总是会注入他们想要的任何 IThingSource。但是,这太难用了;消费者想要新建一个 ThingMaker 并开始制作 Things,然后在几个月后在需要时注入其他东西。在我看来,这只剩下几个选择:
- 省略混蛋构造函数;强制 ThingMaker 的消费者了解 IThingSource,了解 ThingMaker 如何与 IThingSource 交互,查找或编写具体类,然后在其构造函数调用中注入实例。
- 省略混蛋构造函数并提供单独的工厂、容器或其他引导类/方法;以某种方式让消费者明白他们不需要编写自己的 IThingSource;迫使 ThingMaker 的消费者找到并了解工厂或引导程序并使用它。
- 保留混蛋构造函数,使消费者能够“新建”一个对象并使用它运行,并处理对 DefaultThingSource 的可选静态依赖。
男孩,#3 确实看起来很有吸引力。还有其他更好的选择吗? #1 或 #2 似乎不值得。
【问题讨论】:
-
为什么对 DefaultThingSource 的依赖比对 IThingSource 的依赖更糟?选择#3。
-
因为 DefaultThingSource 可能是一个非常具体的实现,它依赖于另一个程序集中的外部系统,几个月后很可能会过时; IThingSource 永远是正确的,永远不会绑定到特定的实现。
-
显然我不知道 DefaultThingSource 有多复杂。但是,我敢打赌,如果你保持简单并且设计得很好,实际上你会发现你的代码不会像你担心的那样过时——当然还不足以证明所有这些心痛的合理性。
-
这就是依赖反转良好的问题——它可能更灵活,设计更好,但对于新程序员来说并不容易使用。
-
你可能还想看看这篇文章:lostechies.com/jimmybogard/2009/07/03/…
标签: c# .net oop dependency-injection constructor