Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork9.6k
[DependencyInjection] Add#[AutowireMethodOf]
attribute to autowire a method of a service as a callable#54016
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
[DependencyInjection] Add#[AutowireMethodOf]
attribute to autowire a method of a service as a callable#54016
Uh oh!
There was an error while loading.Please reload this page.
Conversation
d6df122
to963b4d6
CompareWhat is the reason to create a new attribute instead of making |
#[AutowireMethodOf]
attribute to autowire a method of a service as a callable#[AutowireMethodOf]
attribute to autowire a method of a service as a callable963b4d6
to8b85b8f
Compare
Because method is already optional and it currently means |
alexandre-daubois commentedFeb 20, 2024 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
Really subjective point of view here, I definitely see an improvement of "instant understanding of what's being done". I think having this "alias attribute" helps to get what's happening at first sight, where the existing notation needs a bit of reflection before getting it. It feels more human friendly to me |
What are the benefits about |
Only one con IMHO, if you refactor the method name via IDE this code breaks, I know it’s the same problem for the long attribute version. Not sure I would use it, because if you have no tests and even with static analysis this bug can go to prod. Sounds like a footgun but indeed nice DX |
@Kocal my repositories are final so I cannot mock them, so I would need an interface. This way you don’t need an interface, can have a final class and you can easily test it. |
think about testing a service that has CommentRepository as a dependency: you cannot test it without having a database or without heavy mocking. Query functions are just trivial to replace instead. |
Kocal commentedFeb 20, 2024 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
Hum alright, I can understand the issue, but then doesn't it make sense to create by yourself a invokable class that you can easily mock? IINW you lose the autocompletion/static analysis by using |
nicolas-grekas commentedFeb 21, 2024 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
It's like invokable controllers vs action methods: everyone their preferences 🤷 Mine is this attribute because of the low verbosity: just write a repository, and still get decoupling without creating a myriad of class boilerplate.
true with the current tooling, but this is fixable since the tools can very well be taught about the attribute. On this topic also the current situation is similar and the proposed attribute doesn't bring anything new. |
Alright thanks for the explanations :) |
You mentionned "query" but -naive question- would this work with setters / persisters too ? Could this work ? publicfunction__invoke( #[AutowireMethodOf(CommentRepository::class)]\Closure$saveComment, #[MapRequestPayload]Comment$comment,) {$saveComment($comment);} |
@smnandre yes of course |
840e2f4
to139cc14
Compare139cc14
to0dface6
ComparePR updated with better error handling and a test case. |
0dface6
todbd45e3
Compare… a method of a service as a callable
nicolas-grekas commentedMar 15, 2024 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
FTR, if I define this interface: interface GetCommentPaginatorInterface{publicfunction__invoke(Conference$conference,int$page):Paginator;} Then I can also do native types (vs #[AutowireMethodOf(CommentRepository::class)] GetCommentPaginatorInterface$getCommentPaginator, |
dbd45e3
todf11660
Compare
Uh oh!
There was an error while loading.Please reload this page.
Let's take a controller for example, with one action that has this argument:
#[AutowireMethodOf(CommentRepository::class)] \Closure$getCommentPaginator,
The proposed attribute tells Symfony to create a closure that will call
CommentRepository::getCommentPaginator()
. The name of the method to be called is inferred from the name of the parameter.This is already doable with this syntax, so that the proposed attribute is just a shortcut for this:
Using this style allows turning e.g. entity repositories into query functions, which are way more flexible. But because the existing syntax is quite verbose, i looked for a more concise alternative, so here we are with this proposal.
Benefits:
Because we leverage the existing code infrastructure for AutowireCallable, if I declare this interface:
then I can also do native types (vs a closure) without doing anything else:
#[AutowireMethodOf(CommentRepository::class)] GetCommentPaginatorInterface$getCommentPaginator,