小编典典

有没有混蛋注射的替代方法?(又名穷人通过默认构造函数注入)

c#

我通常会在少数情况下使用“混蛋注射”。当我有一个“适当的”依赖项注入构造函数时:

public class ThingMaker {
    ...
    public ThingMaker(IThingSource source){
        _source = source;
    }

但是,对于我打算用作 公共API的 类(其他开发团队将使用的类),我再找不到比编写具有最可能需要的依赖关系的默认“野兽”构造函数更好的选择了:

    public ThingMaker() : this(new DefaultThingSource()) {} 
    ...
}

这里的明显缺点是,这将对DefaultThingSource创建静态依赖关系;理想情况下,不会存在这种依赖关系,并且消费者将始终注入他们想要的任何IThingSource。但是,这太难使用了。消费者想要更换ThingMaker并开始制作事物,然后数月后在需要时注入其他东西。在我看来,这只剩下几个选择:

  1. 忽略混蛋构造函数;迫使ThingMaker的使用者了解IThingSource,了解ThingMaker如何与IThingSource交互,查找或编写具体的类,然后在其构造函数调用中插入实例。
  2. 省略混蛋构造函数,并提供单独的工厂,容器或其他引导类/方法;以某种方式使消费者了解他们不需要编写自己的IThingSource;迫使ThingMaker的消费者找到并了解工厂或引导者并使用它。
  3. 保留混蛋构造函数,使使用者可以“更新”对象并运行它,并处理对DefaultThingSource的可选静态依赖关系。

男孩,#3肯定看起来很有吸引力。还有其他更好的选择吗?#1或#2似乎不值得。


阅读 327

收藏
2020-05-19

共1个答案

小编典典

据我了解,这个问题与如何使用一些适当的默认值公开松散耦合的API有关。在这种情况下,您可能具有良好的 Local Default
,在这种情况下,依赖项可以视为可选的。处理 可选依赖项的 一种方法是使用 属性注入 而不是 构造函数注入
-实际上,这是属性注入的典型场景。

但是,Bastard Injection的真正危险是当默认值是 Foreign Default时
,因为这将意味着默认构造函数拖拽不希望的耦合到实现默认值的程序集。但是,据我所知,预期的默认值将来自同一程序集,在这种情况下,我看不到任何特殊的危险。

无论如何,您也可以考虑我前面的回答之一中所述的Facade:依赖项注入(DI)“友好”库

顺便说一句,这里使用的术语是基于我的书中的模式语言。

2020-05-19