jj-aa
jj-aa

Reputation: 1039

Symfony setup dependency injection from extended class

I would like to inject to the abstract class like this:

services:
    App\Infrastructure\Persistence\BaseDoctrineRepository:
        arguments:
          $eventStore: '@broadway.event_store'
          $registry: '@doctrine'
          $eventBus: '@broadway.event_handling.event_bus'

, but if do that then I get:

Cannot autowire service "App\Infrastructure\Persistence\User\DoctrineUserRepository": argument "$eventStore" of method "__construct()" references interface "Broadway\EventStore\EventStore" but no such service exists. You should maybe alias this interface to one of these existing services: "broadway.event_store.dbal", "broadway.event_store.in_memory". 

So I need to duplicate code for every repository like this and I would like to avoid it.

services:
    App\Infrastructure\Persistence\User\DoctrineUserRepository:
        arguments:
          $eventStore: '@broadway.event_store'
          $registry: '@doctrine'
          $eventBus: '@broadway.event_handling.event_bus'

Abstract class:

use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;

abstract class BaseDoctrineRepository extends ServiceEntityRepository
{
    public function __construct(ManagerRegistry $registry, EventStore $eventStore, EventBus $eventBus)
    {
        $this->eventStore = $eventStore;
        $this->eventBus = $eventBus;
        parent::__construct($registry, static::REPOSITORY_CLASS);
    }

Class that extends from the abastract (I would like to avoid the constructor):

class DoctrineUserRepository extends BaseDoctrineRepository implements UserRepository
{
    const REPOSITORY_CLASS = User::class;

    public function __construct(ManagerRegistry $registry, EventStore $eventStore, EventBus $eventBus)
    {
        parent::__construct($registry, $eventStore, $eventBus);
    }

Upvotes: 2

Views: 1683

Answers (2)

jj-aa
jj-aa

Reputation: 1039

Following the note indication

If you have a _defaults section in your file, all child services are required to explicitly override those values to avoid ambiguity. You will see a clear error message about this.

of @brucie-alpha link reference, I could manage common dependencies with parent Services. Here is the solution that worked for me since I'm using _defaults section in my services.yaml file

App\Infrastructure\Persistence\BaseDoctrineRepository:
    abstract: true
    public: false
    autowire: false
    autoconfigure: false
    arguments:
      $eventStore: '@broadway.event_store'
      $registry: '@doctrine'
      $eventBus: '@broadway.event_handling.event_bus'

App\Infrastructure\Persistence\User\DoctrineUserRepository:
    parent: 'App\Infrastructure\Persistence\BaseDoctrineRepository'
    public: true
    autowire: false
    autoconfigure: false

Upvotes: 0

Brucie Alpha
Brucie Alpha

Reputation: 1236

did you try this https://symfony.com/doc/current/service_container/parent_services.html?

so basically

services:
    App\Infrastructure\Persistence\BaseDoctrineRepository:
            abstract: true
            arguments:
              $eventStore: '@broadway.event_store'
              $registry: '@doctrine'
              $eventBus: '@broadway.event_handling.event_bus'
    App\Infrastructure\Persistence\User\DoctrineUserRepository:
        parent: App\Infrastructure\Persistence\BaseDoctrineRepository

Upvotes: 2

Related Questions