aicantar
aicantar

Reputation: 25

Ignore missing methods in setter injection

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

Answers (1)

yivi
yivi

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: setLoggerfrom services.yaml, and the logger will be injected in the classes you want, are won't in the classes you don't.

Upvotes: 3

Related Questions