I have a service class MyService
that I use on the controllers by passing it as a parameter in the controller constructor. Needless to say, I use a factory to instantiate the controllers, and use the factory's service locator to retrieve MyService
and then pass it to the instantiated controller.
// factory
$sl = $sl->getServiceLocator();
$ms = $sl->get(MyService::class);
return new MyController($sm);
Now, I need that service in the view. I tried creating a view helper that would take MyService
as a dependency, (similar to the controller) like this:
// view helper factory
$ms = $sl->get(MyService::class);
return new MyServiceViewHelper($ms);
However, it won't correctly instantiate MyService
. It crashes saying:
Catchable fatal error: Argument 1 passed to MyService::__construct() must be an instance of MyRepository, none given, called in /my-path/vendor/zendframework/zend-servicemanager/src/AbstractPluginManager.php
MyService
takes about 3 repositories as dependencies, that are provided naturally by the MyServiceFactory
. However, for some reason, the view helper isn't properly calling the factory or something like that, resulting in an incorrect instantiation.
So my next thought is: maybe this is not how you inject services to the view. So now I ask:
How do I inject services to the views themselves?
Edit: please don't say "pass it from the controller".
The viewhelpers are retrieved from a seperate pluginmanager HelperPluginManager
, the same applies for the controllers which are managed by the ControllerManager
.
To retrieve services from the "root" serviceManager you have to call getServiceLocator()
in your factory as you did in the controller factory.
So your code should be:
// view helper factory
$sl = $sl->getServiceLocator(); //This line will do the trick
$ms = $sl->get(MyService::class);
return new MyServiceViewHelper($ms);