Closed
Description
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
)