我了解依赖项注入,但是还没有那一声“啊”的时刻,它在那儿发出咔嗒声,我真的看到了曙光。

为什么要使用DI?此外,当模拟对象(如使用文件系统的对象)时,该模拟对象将具有什么功能?它只是做虚拟调用(因此不真正使用文件系统)吗?

最佳答案

让我再走几步,离hvgotcodes answer:

class Service {
   Collaborator c = new Collaborator()
}

是具有硬编码依赖项的原始类。
class Service {
    Collaborator c;

    Service(Collaborator c) {
       this.c = c;
    }
}

是带有注入依赖项的新类。

到目前为止,一切都很好。现在,让我们使用Collaborator并从中提取一个接口;称之为ICollaborator。现在,您的新类别的类如下所示:
class Service {
    ICollaborator c;

    Service(ICollaborator c) {
       this.c = c;
    }
}

这买了什么?好了,您可以在代码中创建此类,使其像第一个示例一样运行:
// w00t!  My code compiles and works again!  Ship it!
Service myService = new Service(new Collaborator());

切得很干很容易。当您要使用其他类型的Collaborator时(甚至可能是模拟或伪造的),其美就来自于此。只要它实现了ICollaborator接口,您就很高兴:
// I'm using Fake It Easy for this example.
Service myService = new Service(A.Fake<ICollaborator>());

瞧!现在,您有了一个可单元测试的Service实例,该实例不会拖延具体的Collaborator的行程(这将破坏真正的“单元”测试)。

09-25 18:20