5

我在上一个项目中使用了 Unity,总体上很满意。但是基准测试让我认为我可能会在下一个项目中使用 Simple Injector。

但是,Simple Injector 似乎没有其Container类的接口。这意味着每当我想在方法中使用容器时,我都无法模拟容器进行单元测试。

我很困惑一个真正基于接口起作用的工具,它本身不会成为容器的接口。我知道依赖注入的经典方法除了启动之外不需要容器。(其余的使用构造函数注入。)但我发现当橡胶撞到路时,这并不总是正确的。有时您只需要容器就可以在代码中进行“解析”。

如果我使用 Simple Injector,那么该代码似乎更难进行单元测试。

我对吗?还是我错过了什么?

4

2 回答 2

12

Simple Injector 不包含IContainer抽象,因为:

  • Simple Injector 定义它是没有用的,因为在依赖于IContainer而不是 的情况下Container,您的代码在这种情况下仍将依赖于 Simple Injector,这会导致供应商锁定,而 Simple Injector试图阻止

  • 除了应用程序的Composition Root之外,您编写的任何代码都不应该依赖于容器,也不应该依赖于容器的抽象。两者都是Service Locator 反模式的实现。

  • 单元测试时不应该使用 DI 库。在进行单元测试时,您应该在被测类中手动注入所有假对象或模拟对象。使用容器只会使事情复杂化。也许您正在使用容器,因为手动创建这些类对您来说太麻烦了。这可能表明您的代码存在问题(您可能违反了单一职责原则)或您的测试(您可能缺少创建被测类的工厂方法)。

  • 您可能会使用容器进行集成测试,但一开始就不应该有那么多集成测试。重点应该放在单元测试上,这在应用依赖注入模式时应该很容易。最重要的是,与依赖非常广泛的库定义的接口相比,有更好的方法可以从集成测试中隐藏容器。

  • 自己定义这样的接口(加上一个适配器)是微不足道的,这证明在库中没有它是合理的。正如依赖倒置原则所述,为应用程序定义正确的抽象是您作为应用程序开发人员的工作。倾向于这样做的库和框架在大多数情况下都无法提供适用于所有人的抽象。

  • 库本身不使用该抽象,并且根据框架设计指南,库应该在这种情况下不为您定义此类抽象。如前一点所述,Simple Injector 无论如何都会弄错抽象。

  • 最后但同样重要的是,Simple Injector 容器确实实现了在 mscorlib.dll 中定义的System.IServiceProvider,可用于检索服务对象。

于 2013-04-25T23:08:24.970 回答
0

我认为这里给出的答案完全建立在接受 ServiceLocator 是一种反模式的基础上,而我不相信这在全球范围内被认为是正确的。请参阅 Windows Workflow Foundation 的扩展支持。

反模式链接(及其两个更新)也可能很弱......最新的更新声称违反了封装(“减轻您必须了解代码库中每段代码的每个实现细节的负担。” ) 同时声称依赖关系的前期知识与通过单元测试发现它们在某种程度上不同。无论哪种方式,您都需要知道该给它什么。

总而言之,如果你想遵循定位器模式,要么利用它的 IServiceProvider,要么简化你的容器填充(到一个单例)并为其创建一个静态包装器。

于 2016-09-07T18:02:28.413 回答