为什么Simple Injector没有像Unity这样的IContainer抽象?

Vac*_*ano 5 dependency-injection inversion-of-control unity-container simple-injector

我在上一个项目中使用了Unity,并且非常高兴.但基准测试让我觉得我可以选择Simple Injector来完成我的下一个项目.

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

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

如果我使用Simple Injector,那么代码似乎越来越难以进行单元测试.

我对吗?或者我错过了什么?

Ste*_*ven 12

Simple Injector不包含IContainer抽象,因为那将是无用的:

  • Simple Injector定义它是没用的,因为在这种情况下你的代码仍然依赖于库(因为Simple Injector定义了这个抽象),这导致供应商锁定,Simple Injector 试图阻止.

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

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

  • 您可以将容器用于集成测试,但首先不应该进行那么多的集成测试.重点应放在单元测试上,这在应用依赖注入模式时应该很容易.最重要的是,与依赖于非常宽的库定义的接口相比,有更好的方法可以将容器从集成测试中隐藏起来.

  • 自己定义这样的接口(加上一个适配器)是微不足道的,这证明没有它在库中.作为应用程序开发人员,您可以根据依赖性倒置原则为您的应用程序定义正确的抽象.倾向于这样做的库和框架在提供适合每个人的抽象时大多数时间都会失败.

  • 根据框架设计指南,库本身不使用该抽象,而库应该在这种情况下不为您定义这样的抽象.正如前面所述,Simple Injector无论如何都会让抽象错误.

  • 最后但并非最不重要的是,Simple Injector容器实际上实现了System.IServiceProvider,它在mscorlib.dll中定义,可用于检索服务对象.

  • 但是为什么地球会对集装箱产生依赖?具有(足够)逻辑来测试的类不应该直接依赖于容器.只有基础架构组件(它们是组合根目录的一部分)才应该依赖于容器或容器的抽象.您显然无法测试系统,因为您违反了此规则. (4认同)
  • 该UI显然违反了SRP,这将导致可维护性问题,但是名称为*Service,*Manager,*Helper等的类也是如此.我们称之为[God Classes](http://c2.com/ CGI /维基?GodClass).您的应用程序可能会受益于不同的设计.看看[本文](http://bit.ly/s7tGEH)和[本文](http://bit.ly/s3UUyv),了解如何改进应用程序的设计. (3认同)