Ivan
Ivan

Reputation: 5248

How to inject doctrine repository to service in ZF2

I need to inject my post repository in my post service. I have a PostController, PostEntity, PostServiceInterface and PostRepository.

My post repository contains DQL with methods like findAll(), find($id), etc...

In my PostServiceInterface I have some methods like find, findAll.

Now I want to access to repository to get results from my service. I do not want to write queries directly in service. I try to inject the service into __construct using DI but that doesn't work.

Can someone provide an example on how to do this?

I am using Zend Framework 2 with DoctrineORMModule.

Upvotes: 1

Views: 1034

Answers (1)

edigu
edigu

Reputation: 10089

The best way is writing a custom PostServiceFactory to inject PostRepository to the PostService via constructor injection.

For example:

<?php
namespace Application\Service\Factory;

use Application\Service\PostService;
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;

class PostServiceFactory implements FactoryInterface
{
    /**
     * Creates and returns post service instance.
     *
     * @param ServiceLocatorInterface $sm
     * @return PostService
     */
    public function createService(ServiceLocatorInterface $sm)
    {
        $repository = $sm->get('doctrine.entitymanager.orm_default')->getRepository('Application\Entity\PostService');

        return new PostService($repository);
    }
}

You also need to change the PostService's constructor signature like below:

<?php
namespace Application\Service;

use Application\Repository\PostRepository;

class PostService
{
    protected $repository;

    public function __construct(PostRepository $repository)
    {
        $this->repository = $repository;
    }
}

Finally, in your module.config.php you also need to register your factory in the service manager config:

'service_manager' => array(
    'factories' => array(
        'Application\Service\PostService' => 'Application\Service\Factory\PostServiceFactory',
    )
)

Now, you can get the PostService via the service locator in your controller like below:

$postService = $this->getServiceLocator()->get('Application\Service\PostService');

The PostRepository will be automatically injected into the returned service instance as we coded in our factory.

Upvotes: 3

Related Questions