07.
Decorar un servicio con AsDecorator
Keep on Learning!
If you liked what you've learned so far, dive in! Subscribe to get access to this tutorial plus video, code and script downloads.
If you liked what you've learned so far, dive in! Subscribe to get access to this tutorial plus video, code and script downloads.
Whoops, an error! Please, try again later.
9 Comments
Hi everyone,
First thanks for your great course !
I'm trying to implement another decorator class (RateLimiterButton) in addition to LoggerRemote (with priority 5):
but i'm facing a Circular reference error:
I'm i missing something ?
Thanks
Hey @RobC25!
Small thing, instead of:
Inject the interface instead:
ButtonRemoterefers to the fully decorated service, in this caseRateLimiterRemoteso Symfony is trying to inject it into itself. When usingRemoteInterface, Symfony is smart enough to inject the service it's decorating.Hope that helps!
--Kevin
Thanks a lot, it's more clear now.
Hi All,
Thank you
I would add it's possible to add decorateor like that
#[AsDecorator(RemoteInterface::class)]
Hey @Amine!
You're absolutely right. I should have done that!
-Kevin
Hi there,
One thing is confusing to me here. In the previous chapter we said that we use
#[AsAlias]to tell Symfony which of our two services to use when we type-hintRemoteInterface. This was done while injectingRemoteInterfaceintoLoggerRemote. That's clear.Now, we mark
LoggerRemotewith#[AsDecorator], so anything asks for theButtonRemoteservice, give themLoggerRemoteinstead.So why doesn't it loop in
LoggerRemote? There we injectRemoteInterface, and via#[AsAlias]we expect and getButtonRemote, but via#[AsDecorator]Symfony should try to injectLoggerRemoteinstead. Service self injection?Hey @KamilS!
Yeah, this part can be a bit tough to conceptualize. Let's see if I can explain it a different way:
In the last chapter, when we added
#[AsAlias]toButtonRemote, this told Symfony to injectButtonRemotewhenever we autowireRemoteInterface.Now, when we add
#[AsDecorator(ButtonRemote::class)]toLoggerRemote, Symfony, behind the scenes, swaps theRemoteInterfacealias to now point toLoggerRemote.If we added a new service:
RateLimiterRemotewith#[AsDecorator(ButtonRemote::class)], Symfony would again swap the alias so thatRemoteInterfacepoints toRateLimiterRemote. It always swaps it to the top-level of the decoration stack.I hope that helps but let me know if it's still confusing.
--Kevin
Thanks @kbond!
But the question is: Why is
LoggerRemotestill injected withButtonRemoteand notLoggerRemotewhich is its decorator (or in the future withRateLimiterRemote)? Is it because it is the same class definition and at this stage Symfony does not know about decorating yet, and the current service implementingRemoteInterfaceis stillButtonRemote?Because
LoggerRemotehas theAsDecorator(ButtonRemote::class)attribute, this changes how theLoggerRemoteis wired up. For$inner, a new service is created internally (LoggerRemote.inner), and this is injected for$inner. This new service is the realButtonRemote. Additionally, the decorator logic changes theRemoteInterfacealias to point toLoggerRemoteinstead ofButtonRemote.It might help to use
bin/console debug:container remoteto see these services.I hope this helps but if not, please let me know and I can try and explain differently!
"Houston: no signs of life"
Start the conversation!