Why can't the Logger service be introduced in CompilerPass?

I execute this command

app/console container:debug | grep logger 

it is clear that there is a service called logger :

  logger Symfony\Bridge\Monolog\Logger monolog.logger.assetic Symfony\Bridge\Monolog\Logger monolog.logger.doctrine Symfony\Bridge\Monolog\Logger monolog.logger.event Symfony\Bridge\Monolog\Logger monolog.logger.php Symfony\Bridge\Monolog\Logger monolog.logger.profiler Symfony\Bridge\Monolog\Logger monolog.logger.request Symfony\Bridge\Monolog\Logger monolog.logger.router Symfony\Bridge\Monolog\Logger monolog.logger.security Symfony\Bridge\Monolog\Logger monolog.logger.templating Symfony\Bridge\Monolog\Logger monolog.logger.translation Symfony\Bridge\Monolog\Logger swiftmailer.mailer.default.plugin.messagelogger Swift_Plugins_MessageLogger swiftmailer.plugin.messagelogger alias for "swiftmailer.mailer.default.plugin.messagelogger" 

I am using this code with this code:

 public function process(ContainerBuilder $container) { $clients= $container->findTaggedServiceIds('socket.client'); foreach ($clients as $id => $tags) { $definition = $container->getDefinition($id); $definition->addArgument($container->getDefinition('logger')); } } 

But I got this error:

Symfony \ Component \ dependency injection \ Exception \ InvalidArgumentException] The logger service definition does not exist.

If you change the logger service to monolog.logger.doctrine , then everything is fine, what happened to the log service?

Another interesting thing: even if the above method does not work, it works in yml, I can enter logger service

 services: etc.socket.server: class: %etc.socket.server.class% arguments: [@logger, @event_dispatcher, @etc.encoder,@etc.message.client.request] 

the reason I have to enter the registration service into the code is because I have several socket.client services and they are defined in the code.

Update:

I can find the logger service definition in appDevDebugProjectContainer.xml:

  <service id="logger" class="Symfony\Bridge\Monolog\Logger"> <argument>app</argument> <call method="pushHandler"> <argument type="service" id="monolog.handler.console"/> </call> <call method="pushHandler"> <argument type="service" id="monolog.handler.main"/> </call> <call method="pushHandler"> <argument type="service" id="monolog.handler.debug"/> </call> </service> 

even though I am writing a compiler to enter a registration service, it still does not work

 public function process(ContainerBuilder $container) { $clients = $container->findTaggedServiceIds('micro_pay.socket.client'); foreach ($clients as $id => $tags) { $definition = $container->getDefinition($id); $loggerDefinition=$container->findDefinition('logger'); //$loggerDefinition is null // $definition->addArgument($loggerDefinition); } } 

Why is registrar service so special?

+6
source share
2 answers

Have you tried using the link?

 $definition->addArgument(new Reference('logger')); 

The definition may not yet exist. You never set the actual definition in your argument, you set a link to the service.

+3
source

Try using the findDefinition method instead of getDefinition in the ContainerBuilder class, as described in the doc .

As an example:

Use this:

  $definition->addArgument($container->findDefinition('logger')); 

instead of this:

  $definition->addArgument($container->getDefinition('logger')); 

The main difference between the two methods is to enable the alias service

findDefinition: method "unaliases" returns recursively Example definition

Further link in source code here .

Hope for this help

+3
source

All Articles