Dependency injection 为什么';难道简单的注入器没有像Unity这样的IContainer抽象吗?
我在上一个项目中使用了Unity,总体上很满意。但基准测试让我想我可能会在下一个项目中使用Simple Injector 但是,Simple Injector似乎没有用于其Dependency injection 为什么';难道简单的注入器没有像Unity这样的IContainer抽象吗?,dependency-injection,inversion-of-control,unity-container,simple-injector,Dependency Injection,Inversion Of Control,Unity Container,Simple Injector,我在上一个项目中使用了Unity,总体上很满意。但基准测试让我想我可能会在下一个项目中使用Simple Injector 但是,Simple Injector似乎没有用于其容器类的接口。这意味着,每当我想在方法中使用容器时,我都不能模拟容器进行单元测试 我感到困惑的是,一个真正基于接口功能的工具,其本身如何不会成为容器的接口。我知道依赖注入的经典方法只需要启动时使用容器。(其余部分使用构造函数注入。)但我发现,当橡胶碰到路面时,这并不总是正确的。有时,您只需要容器就可以在代码中进行“解析” 若我
容器
类的接口。这意味着,每当我想在方法中使用容器时,我都不能模拟容器进行单元测试
我感到困惑的是,一个真正基于接口功能的工具,其本身如何不会成为容器的接口。我知道依赖注入的经典方法只需要启动时使用容器。(其余部分使用构造函数注入。)但我发现,当橡胶碰到路面时,这并不总是正确的。有时,您只需要容器就可以在代码中进行“解析”
若我使用简单的注入器,那个么代码似乎更难进行单元测试
我说得对吗?还是我遗漏了什么?Simple Injector不包含
IContainer
抽象,因为:
- 简单的注入器定义它是没有用的,
因为在依赖于
而不是IContainer
的情况下,您的代码在这种情况下仍然依赖于简单注入器,这会导致供应商锁定该简单注入器Container
- 除了应用程序之外,您编写的任何代码都不应该依赖于容器,也不应该依赖于容器上的抽象。这两个都是的实现
- 单元测试时不应使用DI库。当进行单元测试时,您应该在被测试的类中手动注入所有伪对象或模拟对象。使用容器只会使事情复杂化。也许您正在使用容器,因为手动创建这些类对您来说太麻烦了。这可能表明您的代码存在问题(您可能违反了)或您的测试存在问题(您可能缺少测试)
- 您可以使用容器进行集成测试,但是 一开始不应该有那么多集成测试。重点应该放在单元测试上,这在应用依赖注入模式时应该很容易。最重要的是,与依赖于非常广泛的库定义接口相比,有更好的方法在集成测试中隐藏容器
- 自己定义这样的接口(加上一个适配器)是很简单的,这证明在库中没有它是合理的。作为应用程序开发人员,您的工作是按照。倾向于这样做的库和框架在大多数情况下都无法提供适用于所有人的抽象
- 库本身不使用这种抽象,根据,在这种情况下,库不应该为您定义这种抽象。如前一点所述,简单的注入器无论如何都会得到错误的抽象
- 最后但并非最不重要的一点是,Simple Injector容器实际上实现了mscorlib.dll中定义的可用于检索服务对象的功能
总而言之,如果您想遵循定位器模式,可以利用它的IServiceProvider,或者简化容器填充(到一个单实例),并为它创建一个静态包装器。我不想在测试中使用容器。我想对一个使用容器的方法进行单元测试。在这种情况下,我无法模拟容器不使用完整的SimpleInjector逻辑。好的,我们将尝试不同于Unity的方法。为了团结,我们嘲笑IContainer以回报嘲笑。这样我们的单元测试就不会使用(测试)Unity。我们将尝试SimpleInjector。我们将把容器的测试版本传递给被测试对象的构造函数(需要时)。该测试版本将被设置为返回模拟。因此,本质上,我们将在测试中使用SimpleInjector来返回模拟,但在生产中,它将返回在启动时设置的对象。我觉得我必须尝试一下,因为SimpleInjector太快了!!!但为什么那个类对容器有依赖性呢?具有(足够)逻辑来测试的类不应该直接依赖于容器。只有基础设施组件(构成根目录的一部分)应该依赖于容器或容器的抽象。很明显,您在测试系统时遇到了问题,因为您违反了此规则;违反了单一责任原则。请重新考虑你的策略。我热衷于与这种滥用容器的行为作斗争。如果您有疑问,请发布一些实际的示例,说明一个类在SO上注入了容器,或者直接给我发邮件。我很乐意向您解释如何更改设计,以避免出现问题。该UI显然违反了SRP,这将导致可维护性问题,但名称为*Service、*Manager、*Helper等的类也是如此。我们称它们为。您的应用程序可能会受益于不同的设计。看一看并获得一些关于如何操作的想法