0

I'm trying to inject a repository into a service and for that purpose I'm defining services.yml file this way:

parameters:
    user.repository.class: App\UserBundle\Repository\UserRepository
    user_repository.factory_argument: App\UserBundle\Usuario
    user_repository.factory_argument2: Doctrine\ORM\Mapping\ClassMetadata
    user.service.class: App\UserBundle\Services\UserServiceImpl
services:
    app_user.registration.form.type:
        class: App\UserBundle\Form\Type\RegistrationFormType
        arguments: [%fos_user.model.user.class%]
        tags:
            - { name: form.type, alias: app_user_registration }
    login_listener:
        class: 'App\UserBundle\Listener\LoginListener'
        arguments: ['@security.context', '@doctrine', '@service_container']
        tags:
            - { name: 'kernel.event_listener', event: 'security.interactive_login' }
    app.user.repository:
        class: "%user.repository.class%"
        factory-service: doctrine.orm.entity_manager
        factory-method: getRepository
        arguments: [%user_repository.factory_argument%, %user_repository.factory_argument2%]
    user.service:
        class: "%user.service.class%"
        arguments: [ @app.user.repository ]

The problem is in the app.user.respository arguments definition: arguments: [%user_repository.factory_argument%, %user_repository.factory_argument2%]

I get error:

PHP Catchable fatal error: Argument 2 passed to Doctrine\ORM\EntityRepository::__construct() must be an instance of Doctrine\ORM\Mapping\ClassMetadata, string given

I was following this post which actually defines these arguments in a different way, but that's not working for me, maybe it was done for a previous version of symfony or doctrine.

EDIT

There was a typo in 'factory_service` as noted in comments, still I'm going in circles through same error, I don't know if I need to configure parameters interfaces or classes implementing those interfaces

parameters:
    user.repository.class: App\UserBundle\Repository\UserRepository
    user_repository.factory_argument: App\UserBundle\Entity\Usuario
    user.service.class: App\UserBundle\Services\UserServiceImpl
    user.service.argument: App\UserBundle\Repository\UserRepository
services:
    app_user.registration.form.type:
        class: App\UserBundle\Form\Type\RegistrationFormType
        arguments: [%fos_user.model.user.class%]
        tags:
            - { name: form.type, alias: app_user_registration }
    login_listener:
        class: 'App\UserBundle\Listener\LoginListener'
        arguments: ['@security.context', '@doctrine', '@service_container']
        tags:
            - { name: 'kernel.event_listener', event: 'security.interactive_login' }
    app.user.repository:
        public: true
        class: "%user.repository.class%"
        factory_service: doctrine.orm.entity_manager
        factory_method: getRepository
        arguments: [%user_repository.factory_argument%] #, %user_repository.factory_argument2%]
    user.service:
        class: "%user.service.class%"
        arguments: [%user.service.argument%]

And these are my classes:

UserRepositoryInterface:

<?php
namespace App\UserBundle\Repository;

use Doctrine\Common\Persistence\ObjectRepository;

interface UserRepositoryInterface extends ObjectRepository
{
    public function fetch($id_or_email);
}

UserRepository:

<?php

namespace App\UserBundle\Repository;

use Doctrine\ORM\EntityRepository;

class UserRepository extends EntityRepository
                     implements UserRepositoryInterface
{
    public function fetch($id_or_email)
    {
        if (!$id_or_email) return;

        $user = $this->find($id_or_email);

        return $user;
    }
}

UserService (interface)

<?php

    namespace App\UserBundle\Services;

    use Guzzle\Service\ClientInterface;

    interface UserService
    {
        public function getUser($id_or_email);
    }

UserServiceImpl:

<?php

namespace App\UserBundle\Services;

use Guzzle\Service\ClientInterface;
use Doctrine\ORM\EntityRepository;
use App\UserBundle\Repository;

class UserServiceImpl implements UserService {

protected $userRepository;

public function __construct(UserRepositoryInterface $fooRepository) //
{
    $this->userRepository = $fooRepository;
}

public function getUser($em, $id_or_email=null)
{
    error_log("#### getUSer {$id_or_email} ####");

    if (!$id_or_email) return;

    return $this->userRepository->fetch($id_or_email);
}

}

K. Weber
  • 2,643
  • 5
  • 45
  • 77
  • Drop the second argument. It's only needed if you want to use a different meta data object(not class). Which you almost certainly do not want to do. BTW, for this particular case, there is really no value in using parameters for service arguments. There is really nothing that can be overridden. Just makes your service definition harder to read. – Cerad Jul 17 '14 at 18:22
  • It's generally a good idea to copy/paste in code when asking a question. I suspect you are really using factory_service and not factory-service. – Cerad Jul 17 '14 at 18:28
  • @Cerad , yes, there was a typo in `factory-service` but still have the arguments problem – K. Weber Jul 17 '14 at 18:36
  • You are not understanding the difference between services and parameters and class names and objects. Your updated question shows you passing the repository class name to your implementation and not the service (aka object). Get rid of all those parameters. They just confuse things. – Cerad Jul 17 '14 at 18:51

1 Answers1

0

As I mentioned in my comment, you need to drop the second argument to the factory. Here is a working example:

cerad_game__entity_manager__doctrine:
    alias: doctrine.orm.games_entity_manager

cerad_game__team_repository__doctrine:
    class:  Cerad\Bundle\GameBundle\Doctrine\EntityRepository\TeamRepository
    factory_service: 'cerad_game__entity_manager__doctrine'
    factory_method:  'getRepository'
    arguments:  
        - 'Cerad\Bundle\GameBundle\Doctrine\Entity\Team'

Your service should look like this:

app.user.repository:
    class: App\UserBundle\Repository\UserRepository
    factory_service: doctrine.orm.entity_manager
    factory_method: getRepository
    arguments:
        - App\UserBundle\Usuario
Cerad
  • 48,157
  • 8
  • 90
  • 92