According to Marco Pivetta’s thought with this , this old question and my answer to another question
I interrogated myself about how best to use our services in a Zend Framework 2 application.
In fact, we can use ServiceLocatorAwareInterface in combination with ServiceLocatorAwareTrait . With fact In ZF3, the service locator will be removed in the controller . Perhaps they will also remove this interface or advise people who do not use it, it makes sense.
The only way I see how our services can be designed is:
Do not use ServiceLocator in your Services, use DependancyInjection.
The problem is this:
Some projects are so large that you have:
- 15 classes of services for one workflow.
- A class of service with 15 dependencies.
- Choose your nightmare ...
An example of what you might need in a service:
- Return formManager (you cannot call it in the controller)
- You may need your ViewRenderer to render the template before returning the HTML string to the view via AJAX and a JSON response;
- You may need to return the translator or any service you want to provide ZF2
- Get an object manager, if you have several databases, add an account here
- Get other services like MailService, ExportService, ImportService, etc.
- If you need to download specific services, it depends on the client (a multi-client website in BtoB ... adds somes services because you cannot load | an AbstractFactory call)
Perhaps for some of these points they can be solved with tricks that I do not know.
My question is:
Is it good to have 15 or more dependencies for one service? and abandon ServiceLocator, in controllers, but also in services?
Edit Comment
To illustrate my point, I insert one of my constructors:
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(); }
As you can see, ToolboxService is an object with several dependencies. This service is in my application folder and almost everywhere. I have 2 object managers (connecting to 2 databases, but maybe soon I will need a third ...)
You can see that I use serviceLocator through a dependency, so this service does not implement ServiceLocatorAwareInterface . If I do not use it, I am lyrically screwed to my AbstractFactory call with
// 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); }