Declare the same service in several bundles

1

Good morning everyone. I am developing an application using Symfony 2.8 exactly and I have a question about how to organize the declarations of my entity normalization services. I do it in this way to be able to parse JSON in a comfortable and correct way the objects that I store in my BD, I paste the code to clarify a bit of what the subject is:

namespace XXX\XXXBundle\Normalizer;

use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
use Symfony\Component\Serializer\Normalizer\SerializerAwareNormalizer;
use ...

class ReservaNormalizer extends SerializerAwareNormalizer implements NormalizerInterface {

   public function normalize($object, $format = null, array $context = array()) {
        return [
            'reserva_id'     =>  $object->getId(),
            'reserva_nombre'  =>  $object->getNombre(),
             ...
        ];
    }

    public function supportsNormalization($data, $format = null) {
        return $data instanceof Reserva;
    }

}

After this I configure the services.yml file (main, the app / config) as follows:

services:
    ...

    # JSON Encoder
    default.encoder.json:
        class: 'Symfony\Component\Serializer\Encoder\JsonEncoder'

    # Serializer
    symfony.serializer:
        class: 'Symfony\Component\Serializer\Serializer'
        arguments:
            0:
                - '@xxx.normalizer.xxx'
                - '@otro.normalizer.mas'
                - '...otro...'
                - '@serializer.normalizer.object'
            1:
                - '@default.encoder.json'

And in the services.yml of each bundle:

services:
    # XXX Normalizer
    xxx.normalizer.xxx:
        class: 'XXX\XXXBundle\Normalizer\XXXNormalizer'

What I want is NOT to have to declare all Normalizer settings in arguments 0 of the main service configuration file, in order to have everything sorted and not the whole list together.

If I repeat the

symfony.serializer:
    class: 'Symfony\Component\Serializer\Serializer'

in each file services.yml of each bundle gives me an exception A circular reference has been detected (configured limit: 1) . This I imagine is because when declaring again the same service collides.

Is there any way to do it by applying good practices?

Thanks for the answers in advance.

    
asked by Jose FG 24.11.2016 в 09:25
source

1 answer

1

I do not know if your symfony.serializer needs all the Normalizers or only one in each call, I suppose only one, for this you could use CompilerPass that allows you to modify an initial configuration of a service (or of anything loaded in the container) even dynamically.

You could either define the list of normalizers that you need, if you need all of them, or dynamically load only the one you need, if you only need one.

The steps are: 1) define a class that extends from CompilerPassInterface 2) add that class to your Bundle class

for example to define the compilerPass:

class ServiceCompilerPass implements CompilerPassInterface
{
    public function process(ContainerBuilder $container)
    {
        $container->getDefinition('symfony.serializer')
            ->setArguments([
                new Reference($container->getParameter('normalizer1')),
                new Reference($container->getParameter('normalizer2'))
                ...
            ]);
    }
}

and to include in the stock of your bundle

public function build(ContainerBuilder $container)
{
    parent::build($container);

    $container->addCompilerPass(new ServiceCompilerPass());
}

You can find a good article here: link

And from here you can get something else: link

I hope you help ...

    
answered by 25.11.2016 / 19:29
source