Since version 2.7.0 of zend-mvc the ServiceLocatorAwareInterface
is depricated, so are $this->serviceLocator->get()
calls inside controllers.
Thats why some days ago I did a huge refactoring of all my modules to inject the needed services/objects through constructors using factories for mostly everything.
Sure, I understand why this is the better/cleaner way to do things, because dependendies are much more visible now. But on the other side:
This leads to a heavy overhead and much more never-used class instances, doesn't it?
Let's look to an example:
Because all my controllers having dependencies, I've created factories for all of them.
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, ...);
}
}
The SyncRestService is a complex service class which queries some internal server of our system. It has a lot of dependencies, and is always created if a request comes to the CustomerController. But this sync-service is only used inside the syncAction()
of the CustomerController! Before I was using simply $this->serviceLocator->get('Admin\Service\SyncRestClientService')
inside the syncAction()
so only then it was instantiated.
In general it looks like a lot of instances are created through factories at every request, but the most dependencies are not used. Is this an issue because of my design or it is a normal side-effect behaviour of "doing dependency injection through constructors"?