Testing ZF2。除了让AbstractController(或其他类)实现ServiceLocatorAwareInterface之外,还有其他选择吗?

Testing ZF2。除了让AbstractController(或其他类)实现ServiceLocatorAwareInterface之外,还有其他选择吗?,testing,dependency-injection,zend-framework2,inversion-of-control,service-locator,Testing,Dependency Injection,Zend Framework2,Inversion Of Control,Service Locator,在这里,我们可以读到三个理由来避免控制器内部的$this->getServiceLocator()。我认为这些理由不仅适用于控制器类,而且适用于实现ServiceLocatorAwareInterface接口的任何类 大多数情况下,使用ServiceLocatorAwareInterface获取注入的依赖项被视为反模式?在什么情况下,这种模式不能被视为反模式,为什么 有人能详细说明一下替代解决方案(我想大概是使用Zend\DI)是如何实现的吗?更具体地说,如何避免使用ServiceLocator

在这里,我们可以读到三个理由来避免控制器内部的
$this->getServiceLocator()
。我认为这些理由不仅适用于控制器类,而且适用于实现
ServiceLocatorAwareInterface
接口的任何类

大多数情况下,使用
ServiceLocatorAwareInterface
获取注入的依赖项被视为反模式?在什么情况下,这种模式不能被视为反模式,为什么

有人能详细说明一下替代解决方案(我想大概是使用Zend\DI)是如何实现的吗?更具体地说,如何避免使用
ServiceLocatorAwareInterface
模块、控制器和业务/域类。我有兴趣了解Zend\DI及其解决方案的性能问题

编辑

值得为具有两个或三个依赖项的类定义工厂,而我最后得到的唯一结果是将“注入器代码”(以前的
$this->getServiceLocator()->get($serviceName)
)移动到工厂,而根本不解决测试问题?当然我也要测试我的工厂?还是不

我认为工厂必须保留在对象构建涉及复杂任务的情况下。在我看来,当类只有很少的依赖项和零逻辑(除了依赖项解析之外)工厂时,解决这个问题的方法是过分的。此外,在这个解决方案中,我将以更多的测试代码(工厂)和更多的测试(工厂测试)结束,同时尽量避免在测试实现中使用更少的代码。模拟服务定位器是一件容易的事情,因为接口只有两个方法,模拟代码可以在所有测试用例之间共享

如果我错了,请纠正我;)

Zend\DI可能会有所帮助,但如果有人详细介绍这种解决方案的细节,我会很高兴

编辑2

几周前,Zend网络研讨会(“ZF2领域驱动设计简介”)使用了这种反模式(39:05)。我现在正在徘徊,直到什么时候这才是真正的反模式;)

以及有关此问题的更多信息


Fowler要说的是

解决这个问题其实很容易,通过构造函数注入依赖项。这消除了在大型应用程序中会导致问题的许多魔力

因此,这意味着您需要创建工厂,而不是使用可调用类。 如这里的文档所示:

如果您使用ServiceLocatorAwareInterface,ZF文档(在编写此答案时)不清楚并且仍然使用此接口,则上次ZF2版本(zendframework/zend mvc 2.7.0和+)将抛出
Depracated
警告。采埃孚“大师”不谈论更新文档。如果您不是ZF2专家(在撰写此答案时),很难找到具体的例子


但幸运的是,Rob Allen几年前写了一篇文章,解释了如何删除SL依赖项并将其注入控制器:这就解决了问题。希望这会有帮助

谢谢你的回复,安托万。我同意您的观点,构造函数注入是一种解决方案,但我的问题是如何在ZF2上下文中具体实现该解决方案(或另一种)。例如,我可以在何处定义模块类的工厂?(如果我可以在不更改ModuleManager实现的情况下执行此操作),我将立即编辑我的问题,以添加有关此问题的一些其他问题。再次感谢。这是个人品味的问题。。。我通常将工厂放在上下文文件夹之外。因此,如果有一个控制器“Foo\Controller\IndexController”,我会将工厂放在“Foo\ControllerFactory\IndexControllerFactory”中,如果我错了,请纠正我,但如果你说这是通过接口注入antipatern ServiceLocator,那么zend初始化器对我来说又如何呢?这几乎是一样的事情。当您通过ServiceManager创建类实例时,初始值设定项会检查您的类是否实现了特定的接口,然后使用setter注入依赖项。由于它们导致的问题和较差的实现,许多人认为它们是不好的做法。但你应该试着和奥克拉米乌斯谈谈。。。。