1

自从我了解了依赖注入以来,我很难决定是否应该在类中注入或创建某些东西。

考虑以下不使用 DI 的示例:

class Car
{
    private Wheels _wheels;
    private Chasis _chasis;
    private Fuel _fuel;

    public Car()
    {
        _wheels = new Wheels();
        _chasis = new Chasis();
        _fuel = new Fuel();
    }

    public ExhaustGas Exhaust
    {
        get
        {
            return new ExhaustGas();
        }
    }
}

您会注入哪些在 Car 内部创建的实例?如果是这样,你如何决定?

这是我的推理:

  • 燃料- 由于燃料是从外部来源获得的,我肯定可以看到燃料发生变化的原因,我会向它添加抽象(IFuel)并注入它。
  • 车轮- 尽管车轮是汽车的一部分,但您当然可以轻松更换车轮。所以我说它也应该注入。
  • 底盘- 这个需要更多的思考。底盘是汽车非常重要的一部分,因此将其作为外部依赖项似乎有点奇怪。但是,您当然可以单独在底盘上运行测试,并且可以使用假人对汽车进行测试(尽管我不确定是否应该这样做)。应该注入对象的这样一个重要部分吗?
  • ExhaustGas - 这个更难。我可以注入一个按需创建 IExhaustGas 的工厂,但我不确定是否应该这样做。我不应该将这个实例作为工厂注入,因为它是按需创建的吗?如果不是,在这种情况下我的推理应该是什么?

我很想听听您对我在这里介绍的变量的看法,以及关于您如何决定何时注入以及何时不注入的更通用的推理。

4

1 回答 1

2

根据经验,应该注入所有外部依赖项。原因很简单:您希望能够模拟依赖项以进行测试,并在必要时灵活地替换它们。

为了处理注入所有东西的复杂性,有几种策略。如果您只想注入一些东西,请将其设为可选:

class Foo {

    private _bar
    private _baz

    public Foo(Bar bar = null, Baz baz = null) {
        if (!bar)  bar = new Bar;
        if (!baz)  baz = new Baz;

        _bar = bar
        _baz = baz
    }

}

这仍然具有依赖注入的所有优点,同时避免了必要的实例化疯狂。

或者,使用类似 的工厂CarDependencyFactory,它可以在一个类中实例化所有必需的依赖项。也可以选择将其设为可选。

依赖注入容器/管理器/框架也可以提供帮助。最重要的是,您应该注入所有内容,除非您真的确定永远不需要替换依赖项,并且可以将一段代码耦合到另一段代码。

另请参阅如何不使用静力学破坏您的可测试性

于 2012-11-21T16:49:09.867 回答