8000 Service scope seems to be affecting precedence for tagged services, causing container bootstrap to fail · Issue #28720 · symfony/symfony · GitHub
[go: up one dir, main page]

Skip to content
Service scope seems to be affecting precedence for tagged services, causing container bootstrap to fail #28720
Closed
@AshleyDawson

Description

@AshleyDawson

Symfony version(s) affected: 4.1.6

Description
Dissimilar service scope when tagging services seems to break the precedence of service injection in the container cache bootstrap file.

How to reproduce
Tag a public: true service into a public: false service. E.g.

    app.form.post_processor.post_processor_registry:
        public: false
        class: App\Bundle\FormBundle\PostProcessor\PostProcessorRegistry

    App\Bundle\FormBundle\PostProcessor\NotifyPostProcessor:
        public: true
        arguments:
            - "@app.mailer.message_builder"
            - "@app.mailer.message_sender"
        tags:
            - { name: app.form.post_processor }

With the compiler pass:

<?php

namespace App\Bundle\FormBundle\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;

class PostProcessorCompilerPass implements CompilerPassInterface
{
    /**
     * {@inheritdoc}
     */
    public function process(ContainerBuilder $container)
    {
        if (! $container->has('app.form.post_processor.post_processor_registry')) {
            return;
        }

        $definition = $container
            ->findDefinition('app.form.post_processor.post_processor_registry')
        ;

        $taggedProviders = $container
            ->findTaggedServiceIds('app.form.post_processor')
        ;

        foreach ($taggedProviders as $id => $tags) {
            $definition->addMethodCall('add', [
                new Reference($id)
            ]);
        }
    }
}

This then produces the following bootstrap in var/cache/dev/ContainerYZDvbSj/srcDevDebugProjectContainer.php:

        $u->add(new \App\Bundle\FormBundle\PostProcessor\NotifyPostProcessor($g, $h));

        $u = new \App\Bundle\FormBundle\PostProcessor\PostProcessorRegistry();

Notice that PostProcessorRegistry is instantiated after $u->add(...). This therefore causes the application to fail due to this issue in the service container bootstrap file.

Possible Solution
Workaround is to set all services to the same scope (e.g. all to public)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0