Reputation: 25
I'm using PHP traits as mixins to inject optional services, i.e.
trait Logger
{
private LoggerInterface $logger;
public function getLogger(): LoggerInterface
{
return $this->logger;
}
/**
* Inject logger instance (called by the DI container)
*/
public function setLogger(LoggerInterface $logger): self
{
$this->logger = $logger;
return $this;
}
}
Then I use this trait in a class:
class UserService
{
use Logger;
/* ... */
}
Because this trait can be used in any class, I create a method injection call for all classes in App\
namespace to inject the logger:
App\:
# ...
calls:
- [setLogger, ['@monolog.logger']]
However, when Symfony encounters a service that doesn't implement setLogger
method, it throws an error saying 'Invalid service: method "setLogger()" does not exist.'
Since this injection is supposed to be optional, is there a way to tell Symfony to ignore the call if the method does not exist?
Upvotes: 1
Views: 382
Reputation: 47495
You are kinda reinventing the wheel with this one.
Symfony provides this functionality out of the box.
If a service implements LoggerAwareInterface
(link), Symfony will automatically call setLogger()
on the service to inject the logger service.
And since the same package also includes a LoggerAwareTrait
, (link) you can simply do the following:
class FooService implements LoggerAwareInterface
{
use LoggerAwareTrait;
}
And that's it. If you are using the default autowire/autoconfigure settings, no other configuration needed, and the logger will be automatically injected.
You can implement the above, remove your calls: setLogger
from services.yaml
, and the logger will be injected in the classes you want, are won't in the classes you don't.
Upvotes: 3