从 zend-mvc 的 2.7.0 版开始ServiceLocatorAwareInterface
已删除, Controller 内部的 $this->serviceLocator->get()
调用也是如此。
这就是为什么几天前我对我的所有模块进行了一次巨大的重构,以通过使用工厂的构造函数注入(inject)所需的服务/对象。
当然,我理解为什么这是更好/更干净的做事方式,因为依赖关系现在更加可见。但另一方面:
这会导致沉重的开销和更多从未使用过的类实例,不是吗?
让我们看一个例子:
因为我所有的 Controller 都有依赖关系,所以我为它们都创建了工厂。
CustomerControllerFactory.php
namespace Admin\Factory\Controller;
class CustomerControllerFactory implements FactoryInterface {
public function createService(ServiceLocatorInterface $controllerManager) {
$serviceLocator = $controllerManager->getServiceLocator();
$customerService = $serviceLocator->get('Admin\Service\CustomerService');
$restSyncService = $serviceLocator->get('Admin\Service\SyncRestClientService');
return new \Admin\Controller\CustomerController($customerService, $restSyncService);
}
}
CustomerController.php
namespace Admin\Controller;
class CustomerController extends AbstractRestfulController {
public function __construct($customerService, $restSyncService) {
$this->customerService = $customerService;
$this->restSyncService = $restSyncService;
}
}
module.config.php
'controllers' => [
'factories' => [
'Admin\Controller\CustomerController' => 'Admin\Factory\Controller\CustomerControllerFactory',
]
],
'service_manager' => [
'factories' => [
'Admin\Service\SyncRestClientService' => 'Admin\Factory\SyncRestClientServiceFactory',
]
]
SyncRestClientServiceFactory.php
namespace Admin\Factory;
class SyncRestClientServiceFactory implements FactoryInterface {
public function createService(ServiceLocatorInterface $serviceLocator) {
$entityManager = $serviceLocator->get('doctrine.entitymanager.orm_default');
$x1 = $serviceLocator->get(...);
$x2 = $serviceLocator->get(...);
$x3 = $serviceLocator->get(...);
// ...
return new \Admin\Service\SyncRestClientService($entityManager, $x1, $x2, $x3, ...);
}
}
SyncRestService 是一个复杂的服务类,它查询我们系统的一些内部服务器。它有很多依赖关系,并且总是在请求到达 CustomerController 时创建。但是此同步服务仅在CustomerController 的syncAction()
中使用!在我只是在 syncAction()
中使用 $this->serviceLocator->get('Admin\Service\SyncRestClientService')
之前,所以它才被实例化。
一般来说,看起来很多实例是在每次请求时通过工厂创建的,但大多数依赖项没有被使用。这是我的设计造成的问题,还是“通过构造函数进行依赖注入(inject)”的正常副作用行为?
最佳答案
在我看来,这是通过构造函数进行依赖注入(inject)的正常效果。
我认为您现在有两个选项(不是相互排斥的)来改进您的应用程序的工作方式:
拆分您的 Controller ,以便仅在需要时实例化依赖项。这肯定会产生更多的类、更多的工厂等等,但是您的代码会更符合单一职责原则
你可以使用 Lazy Services , 因此,即使某些服务是整个 Controller 的依赖项,它们实际上只会在第一次被调用时被实例化(所以永远不会在没有调用它们的操作中被实例化!)
关于php - 在没有 serviceLocator->get() 方式的情况下,ZF2 中新的依赖注入(inject)方式是否更加低效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36796060/