I execute this command
app/console container:debug | grep logger
clearly, there is a service named 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 inject the service using 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\DependencyInjection\Exception\InvalidArgumentException] The service definition "logger" does not exist.
If change the logger
service to monolog.logger.doctrine
, then everything is fine, what happened with logger service?
Another interesting thing is that even though the above way didn't work , it works in in yml, I can inject the 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 inject the logger service in code , because I have several socket.client
services, and they are defined in the code.
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 write a compile pass to inject the logger service , it still doesn't 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 the logger service is such special?
Have you tried using the reference instead?
$definition->addArgument(new Reference('logger'));
The definition might not exist yet at this point. You never set the actual definition in your argument, you set a reference to a service.
Try using the method findDefinition
instead of getDefinition
on ContainerBuilder class as described in the doc.
As Example:
Use this:
$definition->addArgument($container->findDefinition('logger'));
instead of this:
$definition->addArgument($container->getDefinition('logger'));
The main difference between the two methods is about the resolutions of aliases service
findDefinition: The method "unaliases" recursively to return a Definition instance
Further reference in the source code here.
Hope this help
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With