根据Marco的Pivetta this的想法,这old question 以及我对an other question
的回答我正在询问自己在Zend Framework 2应用程序中使用我们服务的更好方法。
实际上,我们可以将ServiceLocatorAwareInterface
与ServiceLocatorAwareTrait
结合使用。
事实In ZF3 service locator will be removed in controller他们可能也会删除这个界面,或建议不使用它的人,这是有道理的。
我看到我们的服务如何构建的唯一方法是:
请勿在服务中使用ServiceLocator,请使用DependancyInjection。
问题是:
有些项目非常大,你要么:
服务中可能需要的一些示例:
也许对于其中的一些观点,他们可以通过我不知道的技巧来解决。
我的问题是:
对于一项服务,拥有15个或更多Dependancies是一个好习惯 并放弃控制器中的ServiceLocator,还放弃服务?
根据评论进行修改
为了说明我的观点,我粘贴了一个构造函数:
public function __construct(
ToolboxService $toolboxService,
EntityService $entityService,
UserService $userService,
ItemService $itemService,
CriteriaService $criteriaService,
Import $import,
Export $export,
PhpRenderer $renderer
) {
$this->toolboxService = $toolboxService;
$this->entityService = $entityService;
$this->userService = $userService;
$this->emOld = $this->toolboxService->getEmOld();
$this->emNew = $this->toolboxService->getEmNew();
$this->serviceLocator = $this->toolboxService->getServiceLocator();
$this->itemService = $itemService;
$this->criteriaService = $criteriaService;
$this->import = $import;
$this->export = $export;
$this->renderer = $renderer;
$this->formManager = $this->toolboxService->getFormManager();
}
如您所见,ToolboxService本身就是一个具有多个依赖项的对象。此服务位于我的Application文件夹中,几乎无处不在。 我有2个实体经理(连接到2个数据库,但可能很快,我将需要第三个......)
您可以看到我通过依赖使用serviceLocator,因此该服务不实现ServiceLocatorAwareInterface
。如果我没有使用它,我可以用
// Distribute somes orders depends on Clients
$distributionClass = $this->serviceLocator->get(ucfirst($param->type));
if ($distributionClass instanceof DistributeInterface) {
$distributionClass->distribute($orders, $key);
} else {
throw new \RuntimeException("invalid_type_provided", 1);
}
答案 0 :(得分:3)
假设您要注入ServiceLocator
实例。无法保证ServiceLocator
实际上保留了您的硬依赖关系,从而打破了DI模式。使用构造函数依赖项注入时,您确信所需的所有服务都是真正可用的。如果没有,那么服务的构建就会失败。
使用ServiceLocator
时,您将最终进入实例化的服务类,其中ServiceLocator
可能会或可能不会提供硬依赖项。这意味着您必须编写所有类型的附加逻辑(检查依赖项,抛出异常),以防在您要求时无法从ServiceLocator
实例解析依赖项。编写所有这些代码可能会产生更多的工作,然后注入15个依赖项,最重要的是逻辑将在整个服务中混乱。
此外,您仍需要添加所有setter和getter方法,才能从ServiceLocator
获取服务并使您的服务可以测试。
IMHO注入15个依赖项代码更少,更容易维护,然后注入ServiceLocator
实例。