Is the new way to inject dependencies in ZF2 without the serviceLocator-> get () function more inefficient?

Starting with version 2.7.0, zend-mvc ServiceLocatorAwareInterface loses, so it $this->serviceLocator->get()calls inside the controllers.

That's why a few days ago I did a huge refactoring of all my modules to implement the necessary services / objects through constructors using factories for most of everything.

Of course, I understand why this is a better / cleaner way to do something, because the dependencies are now much more noticeable. But on the other side:

This leads to heavy overhead and much more unused class instances, right?

Let's look at an example:

Since all of my controllers are addicted, I created factories for everyone.

<i> 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. sync-service syncAction() CustomerController! $this->serviceLocator->get('Admin\Service\SyncRestClientService') syncAction(), .

, , , . - " "?

+4
4

-, .

, ( ), :

+7

SyncRestClientService , ( , SyncRestClientService).
syncAction, , . ZF2.

( Zend\Mvc\Controller\Plugin\AbstractPlugin):

<?php
namespace Application\Controller\Plugin;

use Zend\Mvc\Controller\Plugin\AbstractPlugin;

class SyncPlugin extends AbstractPlugin{

    protected $syncRestClientService;

    public function __constuct(SyncRestClientService $syncRestClientService){
        $this->syncRestClientService = $syncRestClientService
    }

    public function sync(){
        // do your syncing using the service that was injected
    }
}

a factory, :

<?php
namespace Application\Controller\Plugin\Factory;

use Application\Controller\Plugin\SyncPlugin;

class SyncPluginFactory implements FactoryInterface
{
    /**
     * @param  ServiceLocatorInterface $serviceController
     * @return SyncPlugin
     */
    public function createService(ServiceLocatorInterface $serviceController)
    {
        $serviceManager = $serviceController->getServiceLocator();
        $syncRestClientService = $serviceManager>get('Admin\Service\SyncRestClientService');
        return new SyncPlugin($syncRestClientService);
    }
}

module.config.php:

<?php
return array(
    //...
    'controller_plugins' => array(
        'factories' => array(
            'SyncPlugin' => 'Application\Controller\Plugin\Factory\SyncPluginFactory',
        )
    ),
    // ...
);

:

protected function syncAction(){
    $plugin = $this->plugin('SyncPlugin');
    //now you can call your sync logic using the plugin
    $plugin->sync();
}

,

+1

, , ( ServiceManager). ...

namespace Admin\Factory\Controller;

class CustomerControllerFactory implements FactoryInterface {

    public function createService(ServiceLocatorInterface $controllerManager) 
    {
        $serviceLocator = $controllerManager->getServiceLocator();

        return new \Admin\Controller\CustomerController($serviceLocator);
    }

}
0

factory .

.

namespace Admin\Controller\Service;

use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
use Admin\Controller\SitesController;
use Admin\Model\Sites as Models;

class SitesControllerFactory implements FactoryInterface
{

    public function createService(ServiceLocatorInterface $serviceLocator)
    {
        $actionName = $serviceLocator->getServiceLocator()->get('Application')->getMvcEvent()->getRouteMatch()->getParam('action');

        $controller = new SitesController();

        switch ($actionName) {
            case 'list':
                $controller->setModel($serviceLocator->getServiceLocator()->get(Models\ListSitesModel::class));
                break;
            case 'view':
                $controller->setModel($serviceLocator->getServiceLocator()->get(Models\ViewSiteModel::class));
                break;
            case 'add':
                $controller->setModel($serviceLocator->getServiceLocator()->get(Models\AddSiteModel::class));
                break;
            case 'edit':
                $controller->setModel($serviceLocator->getServiceLocator()->get(Models\EditSiteModel::class));
                break;
        }

        return $controller;
    }

}

As you can see, I use $serviceLocator->getServiceLocator()->get('Application')->getMvcEvent()->getRouteMatch()->getParam('action');to get the name of the action and use the switch statement to introduce dependencies if necessary. I don't know if this is the best solution, but it works for me.

Hope this helps.

0
source

All Articles