- 
          
 - 
                Notifications
    
You must be signed in to change notification settings  - Fork 5.3k
 
[FrameworkBundle] Document how to decouple controllers from Symfony #21553
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 our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: 7.4
Are you sure you want to change the base?
Conversation
| class MyController | ||
| { | ||
| public function __construct( | ||
| #[AutowireMethodOf(ControllerHelper::class)] | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's still logically coupled to ControllerHelper since the controller explicitly requests a method reference from it AutowireMethodOf(ControllerHelper::class)
the container wiring hides construction details, but conceptually MyController still depends on that specific class being available and compatible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ideally, this wiring config should be defined globally in your project to eliminate the code coupling issue and remove the need to specify AutowireMethodOf in every controller.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not coupled at all. You can run this code without having the DI component nor the ControllerHelper class.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't believe it's only about running this code (which is absolute right), but also about writing this code so it minimizes the ripple effect (the number of places you must modify when changing behavior), that's the kind of coupling I'm referring to.
If adding an adapter forces edits in other parts of the code, you still have coupling (one that is about DI config in your php code)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it works without the framework or the DI component. My concern isn't about those cases (they're fine with this setup) I’m focused on achieving proper decoupling while still using the framework, especially in the context of functional testing.
| { | ||
| public function __construct( | ||
| #[AutowireMethodOf(ControllerHelper::class)] | ||
| private RenderInterface $render, | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
example: let's say I want to replace this render implementation by a custom one, so I create a dedicated adapter for RenderInterface, but I would still need to remove/change the #[AutowireMethodOf(ControllerHelper::class)] line to make it work properly, isn't it? In this case, my code is not fully decoupled.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you don't have to. you can wire any other stuff explicitly anywhere else - test case, DI config, etc
of course, if you want Symfony to autowire for you, you need to change the declaration.
But that's still not coupling: you can run the code without.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(still on the Symfony context) I might be missing something, but based on what I've tested so far, it doesn't seem possible to override this DI config (without using a CP) in a functional test context (the most common for controllers) to use a different adapter for RenderInterface in test env, since the DI attribute takes precedence over any external DI config.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
override this DI config in a functional test context
it must be possible - autowiring attributes are ignored when autowiring is diabled but also when a specific argument is explicitly configured.
| 
           Yonel, I think you are right. Let me ping @nicolas-grekas to see if I missed something or if we should really remove that mention to "decoupled code". Thanks!  | 
    
Fixes #21144.