How to Inject a Repository into a Service in Symfony

How to inject a repository into a service in Symfony?

I found this link and this worked for me:

parameters:
image_repository.class: Mycompany\MainBundle\Repository\ImageRepository
image_repository.factory_argument: 'MycompanyMainBundle:Image'
image_manager.class: Mycompany\MainBundle\Service\Image\ImageManager
image_manipulator.class: Mycompany\MainBundle\Service\Image\ImageManipulator

services:
image_manager:
class: %image_manager.class%
arguments:
- @image_manipulator
- @image_repository

image_repository:
class: %image_repository.class%
factory_service: doctrine.odm.mongodb
factory_method: getRepository
arguments:
- %image_repository.factory_argument%

image_manipulator:
class: %image_manipulator.class%

Symfony - inject doctrine repository in service

As you are using Symfony 3.4, you can use a much simpler approach, using ServiceEntityRepository. Simply implement your repository, let it extend class ServiceEntityRepository and you can simply inject it. (At least when using autowiring – I haven’t used this with classic DI configuration, but would assume it should also work.)

In other words:

namespace App\Repository;

use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Common\Persistence\ManagerRegistry;

class ExampleRepository extends ServiceEntityRepository
{
/**
* @param ManagerRegistry $managerRegistry
*/
public function __construct(ManagerRegistry $managerRegistry)
{
parent::__construct($managerRegistry, YourEntity::class);
}
}

Now, without any DI configuration, you can inject the repository wherever you want, including controller methods.

One caveat (which equally applies to the way you try to inject the repository): if the Doctrine connection is reset, you will have a reference to a stale repository. But IMHO, this is a risk I accept, as otherwise I won’t be able to inject the repository directly..

How to inject a repository inside a service?

So I did a bit of experimenting and this seems to work:

// services.yml
AppBundle\Repository\CommentsRepository:
factory: 'doctrine.orm.entity_manager:getRepository'
arguments: ['AppBundle\Entity\Comments']

That should give autowire enough information to inject the repository.

Symfony 3.3 injecting repositories into services

I was able to do this using the following services.yml:

services:
# default configuration for services in *this* file
_defaults:
autowire: true
autoconfigure: true

# this means you cannot fetch services directly from the container via $container->get()
# if you need to do this, you can override this setting on individual services
public: false

# makes classes in src/AppBundle available to be used as services
# this creates a service per class whose id is the fully-qualified class name
CbmLtd\UvmsBundle\:
resource: '../../vendor/cbmltd/uvms-bundle/*'
exclude: '../../vendor/cbmltd/uvms-bundle/{Entity,Repository}'

CbmLtd\UvmsBundle\Repository\DealerRepository:
factory: doctrine.orm.entity_manager:getRepository
arguments:
- CbmLtd\UvmsBundle\Entity\Dealer

UvmsApiV1Bundle\:
resource: '../../src/UvmsApiV1Bundle/*'
exclude: '../../src/UvmsApiV1Bundle/{Entity,Repository}'

I had to change my controller slightly but it's working now.

Error injecting repository into service with Symfony3.3

Repositories cannot be directly instantiated. You need to use EntityManager::getRepository

So you will need to define your repos in services.yml

// services.yml
AppBundle\Repository\UserRepository:
factory: 'doctrine.orm.entity_manager:getRepository'
arguments: ['AppBundle\Entity\User']

And then autowire injection should work.

I'll be curious to see if autowire really does catch on. It is inherently frustrating since some services are wired as if by magic while others require manual intervention which could result in a bit of a mess.

Symfony: use a service from Repository (similar than from Controller)

Injecting service into a repository is bad practice and you shouldn't do it.

Although if want solution which will work with get->('any.service') it will look like following:

In services.yml

app.some_service:
class: 'AppBundle\Repositories\SomeEntityRepository'
factory: ["@doctrine.orm.entity_manager", getRepository]
arguments:
- 'AppBundle\Entity\SomeEntity'
calls:
- [setContainer, ["@service_container"]]

In your repository class:

class SomeEntityRepository implements ContainerAwareInterface
{
use ContainerAwareTrait;

public function foo()
{
$bar = $this->container->get('app.bar_service');
}
}

It's also better to inject individual service rather than the service container.



Related Topics



Leave a reply



Submit