在少数情况下,我最常使用的是“私生子注射”。当我有一个“合适的”依赖注入构造器时:
public class ThingMaker {
...
public ThingMaker(IThingSource source){
_source = source;
}
但是,对于我打算作为公共API(其他开发团队将使用的类)的类,我再也找不到比编写具有最可能需要的依赖项的默认“混蛋”构造函数更好的选择了:
public ThingMaker() : this(new DefaultThingSource()) {}
...
}
这里的明显缺点是,这会创建对DefaultThingSource的静态依赖;理想情况下,不会有这样的依赖,消费者总是会注入他们想要的任何IThingSource。然而,这太难使用了;消费者想要新的ThingMaker并开始制作东西,然后几个月后当需要时再注入其他东西。在我看来,这只剩下几个选择:
天哪,#3看起来确实很有吸引力。还有其他更好的选择吗?#1或#2似乎不值得。
发布于 2011-07-19 05:59:58
据我所知,这个问题涉及到如何用一些适当的默认值公开一个松散耦合的API。在这种情况下,您可能有一个良好的本地默认,在这种情况下,可以将依赖项视为可选的。处理可选依赖的一种方法是使用属性注入而不是构造函数注入-事实上,这是属性注入的一种典型场景。
然而,混账注入的真正危险是当缺省值是外部缺省时,因为这将意味着缺省构造函数拖着一个不需要的耦合到实现缺省值的程序集。然而,根据我对这个问题的理解,预期的默认值将来自同一个程序集,在这种情况下,我看不到任何特别的危险。
在任何情况下,您都可以考虑使用Facade,就像我之前的回答之一所描述的:Dependency Inject (DI) "friendly" library
顺便说一句,这里使用的术语是基于my book的模式语言。
发布于 2011-07-19 00:07:30
我的权衡是在@BrokenGlass上旋转:
1)唯一构造函数是参数化构造函数
2)使用工厂方法创建ThingMaker并传入默认源代码。
public class ThingMaker {
public ThingMaker(IThingSource source){
_source = source;
}
public static ThingMaker CreateDefault() {
return new ThingMaker(new DefaultThingSource());
}
}
显然,这并不能消除您的依赖关系,但它确实让我更加清楚地看到,这个对象有一些依赖关系,如果调用者愿意的话,可以深入研究这些依赖关系。如果你喜欢(CreateThingMakerWithDefaultThingSource),你可以让工厂方法更明确,如果这有助于理解的话。与覆盖IThingSource工厂方法相比,我更喜欢这种方法,因为它继续偏爱组合。您还可以在DefaultThingSource过时时添加新的工厂方法,这样就可以清楚地找到使用DefaultThingSource的所有代码并将其标记为要升级。
你在你的问题中涵盖了可能性。为了方便起见,或者为了方便,或者为了在类本身内部提供一些方便,在其他地方使用工厂类。唯一另一个不吸引人的选择是基于反射的,它进一步隐藏了依赖性。
发布于 2011-07-18 21:41:13
一种替代方法是在ThingMaker
类中有一个factory method CreateThingSource()
,它为您创建依赖项。
为了进行测试,或者如果您确实需要其他类型的IThingSource
,则必须创建ThingMaker
的子类并覆盖CreateThingSource()
以返回所需的具体类型。显然,只有当您主要需要能够注入依赖项以进行测试,但对于大多数/所有其他目的不需要另一个IThingSource
时,这种方法才是值得的
https://stackoverflow.com/questions/6733667
复制相似问题