ZF2 - ServiceManager dependencies in controllers

I am trying to convert my beta DI code to version ZF2. Right now, I am falling at the very beginning, and there seems to be no documentation about injecting material into controllers, which makes me think that it is not normal to have dependencies in the controller?

Right now I'm just doing var_dump('blah');exit; to try to run some code ... I tried a few things and now I expected this to work:

module.config.php

 'controllers' => array( 'invokables' => array( 'indexController' => 'Application\Controller\IndexController', ) ) 

module.php

 public function getControllerConfig() { return array( 'factories' => array( 'indexController' => function(ControllerManager $cm) { var_dump('blah');exit; }, ), ); } 

Nothing is happening right now, and it's rather unpleasant ... I read something about creating factories for each controller, but I have 33, and I find it completely insane and stupid ...?

What I'm trying to implement is stuff like userMapper for capturing / saving users. Thus, registerAction creates a user in the database using userMapper, and when you try to log in, it uses userMapper to check if the user is there, etc.

+4
source share
3 answers

The problem here is that 'indexController' is defined as invokable and factory. I think he checks invokables first, so when he finds what he is looking for, he never tries to run the code in the factory. Just delete the entry in the invokables array.

I just wrote a post on this topic. Instead of creating a separate factory class for each controller, you can do this with a closure. If the dependencies are invokable or easily configured using an array of parameters, this is even simpler, all you need is an array that lists the classes that can be entered. Check out http://zendblog.shinymayhem.com/2013/09/using-servicemanager-as-inversion-of.html

+2
source

you can easily do it like this in any Module.php

 public function onBootstrap(\Zend\EventManager\EventInterface $e) { $serviceManager = $e->getApplication()->getServiceManager(); $myDependency = /*something*/; $controllerLoader = $serviceManager->get('ControllerLoader'); $controllerLoader->addInitializer(function ($controller) use ($myDependency) { if (method_exists($instance, 'injectMyDependency')) { $controller->injectMyDependency($myDependency); } }); } 

it would be a little cleaner to let the controllers that need the dependency implement the interface and check if the controller is an instance of that interface and then install it, and not just check if this method exists ...

+1
source

Below, my initializer code is entered in an arbitrary class. At first it was difficult to understand - automatic introduction to the controller when creating the instance, you must define the initializer in the "initializer" section of the "controllers" module.config.php section - not in the "service_manager" section. In principle, to create universal "Aware Interfaces" that will be effective for controllers, and the rest - the corresponding initializer paralipes should be displayed in both sections as a whole ...

 // module/SkeletonClassmapGenerator/Item/ImplementedItem/ImplementedItemInitializer.php namespace SkeletonClassmapGenerator\Item\ImplementedItem; use Zend\ServiceManager\InitializerInterface; use SkeletonClassmapGenerator\Provider\GenericInitializerTrait; class ImplementedItemInitializer implements InitializerInterface { static protected $T_NAMESPACE = __NAMESPACE__; static protected $T_CLASS = __CLASS__; use GenericInitializerTrait; } 

Then for the attribute (obviously shared between all initializers) ...

 // module/SkeletonClassmapGenerator/Provider/GenericInitializerTrait.php namespace SkeletonClassmapGenerator\Provider; use Zend\ServiceManager\ServiceLocatorInterface; trait GenericInitializerTrait { public function initialize($instance, ServiceLocatorInterface $serviceLocator) { if (isset(static::$T_CLASS)&&(isset(static::$T_NAMESPACE))){ $classname = explode('\\', static::$T_CLASS); $class = end($classname); preg_match('/([\w]*)Initializer$/i', $class,$matches); $basename = $matches[1]; if(is_subclass_of($instance,static::$T_NAMESPACE.'\\'.$basename.'AwareInterface')) { $sl = (method_exists($serviceLocator,'getServiceLocator'))? $serviceLocator->getServiceLocator():$serviceLocator; $dependency = $sl->get(static::$T_NAMESPACE.'\\'.$basename.'Interface'); // I use 'Interface' as postfix for Service Manager invokable names $instance->{'set'.$basename}($dependency); } } } 

}

0
source

Source: https://habr.com/ru/post/1434060/


All Articles