I am new to Zend Framework 2 and I am new to the concept of dependency injection, service layer and factory.
I am currently trying to create a service layer that required Service Locator. Once that works then I need to pass this service to a controller but I can't quite get it to work. I always get this error message in PageControllerFactory.php
Zend\ServiceManager\ServiceManager::get was unable to fetch or create an instance for `Template\Service\PageService`
Can anybody help guiding me into the right direction on why I am unable to fetch or create an instance for Template\Service\PageService
?
I was thinking maybe I didn't include it module.config.php
but isn't that what's service_manager
factories
supposed to do?
module.config.php
'controllers' => array(
'factories' => array(
'Template\Controller\Factory\PageControllerFactory',
),
),
'service_manager' => array(
...
'factories' => array(
'Template\Service\Factory\PageServiceFactory',
'Template\Service\Factory\SharedServiceFactory',
),
...
),
Here is a Factory that I inject Service Locator in for SharedService
SharedServiceFactory.php
namespace Template\Service\Factory;
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
use Template\Service\SharedService;
class SharedServiceFactory implements FactoryInterface
{
public function createService(ServiceLocatorInterface $serviceLocator)
{
return new SharedService($serviceLocator->getServiceLocator());
}
}
I then use __construct()
to retrieve the Service Locator.
SharedService.php
namespace Template\Service;
use Zend\ServiceManager\ServiceLocatorInterface;
use Template\Service\SharedServiceInterface;
class SharedService implements SharedServiceInterface
{
protected $serviceLocator;
...
public function __construct(ServiceLocatorInterface $serviceLocator)
{
$this->serviceLocator = $serviceLocator;
}
...
The code breaks here in PageControllerFactory.php. I assume that $parentService->get('Template\Service\PageService')
can't retrieve Template\Service\PageService
here. That's why it throws an error.
PageControllerFactory.php
namespace Template\Controller\Factory;
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
use Template\Controller\PageController;
class PageControllerFactory implements FactoryInterface
{
public function createService(ServiceLocatorInterface $serviceLocator)
{
$parentService = $serviceLocator->getServiceLocator();
$pageService = $parentService->get('Template\Service\PageService');
$sharedService = $parentService->get('Template\Service\SharedService');
return new PageController($pageService, $sharedService);
}
}
PageController.php
namespace Template\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use Template\Service\PageServiceInterface;
use Template\Service\SharedServiceInterface;
class PageController extends AbstractActionController
{
protected $pageService;
protected $sharedService;
public function __construct(
PageServiceInterface $pageService,
SharedServiceInterface $sharedService
) {
$this->pageService = $pageService;
}
...
Instead of this :
'service_manager' => array(
...
'factories' => array(
'Template\Service\Factory\PageServiceFactory',
'Template\Service\Factory\SharedServiceFactory',
),
...
),
declare this :
'service_manager' => array(
...
'factories' => array(
'Template\Service\PageService' => 'Template\Service\Factory\PageServiceFactory',
'Template\Service\SharedService' => 'Template\Service\Factory\SharedServiceFactory',
),
...
),
Factories in config has ot be declared on this format : [Alias => [FQCN of factory]]
And via the service locator you have to call the alias.