-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[FrameworkBundle] call setContainer() for autowired controllers #23239
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
Conversation
Isn't this missing |
IMO it should be the role of the DI component to call the |
Why doesn't |
Because PSR 11 isn't compatible with it. |
The PR now handles the |
Have you already tried with the DI Extra Bundle ? |
Why do we need to inject container if the controller is autowired? If one is changing the controllers to new autowired way it should expect to remove the direct access to the container along the way. |
I agree. It also feels weird injecting it at runtime in a service. In #23200 (comment) I suggested another fix allowing the |
I think the container can still be useful in a controller even with autowiring. For instance autowiring cannot be used when the service to be called is only known at runtime (from the db for instance):
Of course, using the container that way is not usually a good practice, but I believe that in some situations it can help reduce code size... |
I just checked again and this is only an issue I was able to reproduce with routes registered by FOSRestBundle. The routes that are being registered then reference the controller with a pattern like |
@ogizanagi I am 99% sure you're right about this not fixing the issues with the DI Extra Bundle, but that's probably something that needs to be addressed in that bundle, not here. |
yeah, if JMSDIExtraBundle replaces the whole resolver without reusing the Symfony implementation through decoration or inheritance, it means they have to update their bundle each time Symfony adds a new feature. This is their issue. |
But the same goes for fos rest: is it normal to use the single colon notation usually used for controller as services ? |
@ogizanagi IIRC, maybe they wanted to define the route for container as a service. |
@ogizanagi Actually it's one colon for services and two for controller classes that must be instantiated by the controller resolver. |
@xabbuh no. 2 colons is not for services. It is for normal callables (as it is the syntax used for callables in PHP) |
see FriendsOfSymfony/FOSRestBundle#1721 which could also be a fix However, I still think that the main inconsistency is that the |
@stof good catch, I fixed my comment accordingly |
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 this is the right fix. ContainerAwareInterface
is here for something, setContainer
must be called by the resolver when it is detected like what does the serializer when detecting NormalizerAwareInterface
for instance.
return parent::createController($controller); | ||
$resolvedController = parent::createController($controller); | ||
|
||
if (1 === substr_count($controller, ':') && is_array($resolvedController)) { |
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.
shouldn't this be done in the parent class instead, which is the one supporting container injection ?
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.
IMO that would be inconsistent as the parent class isn't doing this for instances it creates itself either.
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.
hmm indeed. I missed the fact that injection was done in this class in a separate method
hmm, actually, can we have a test covering this case to prevent regressions ? |
I'll check |
tests added |
Thank you @xabbuh. |
…llers (xabbuh) This PR was merged into the 3.3 branch. Discussion ---------- [FrameworkBundle] call setContainer() for autowired controllers | Q | A | ------------- | --- | Branch? | 3.3 | Bug fix? | yes | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #23200, FriendsOfSymfony/FOSRestBundle#1719 | License | MIT | Doc PR | Previously, you either did not use controllers as services or you explicitly wired everything yourself. In case of a non-service controller the FrameworkBundle took care of calling `setContainer()` inside the `instantiateController()` method: ```php protected function instantiateController($class) { $controller = parent::instantiateController($class); if ($controller instanceof ContainerAwareInterface) { $controller->setContainer($this->container); } if ($controller instanceof AbstractController && null !== $previousContainer = $controller->setContainer($this->container)) { $controller->setContainer($previousContainer); } return $controller; } ``` With the new autowired controllers as services this is no longer happening as controllers do not need to be instantiated anymore (the container already returns fully built objects). Commits ------- 1d07a28 call setContainer() for autowired controllers
…nerAwareInterface (fixes #1666)" This reverts commit faccea6. Fixed in symfony/symfony#23239 (Symfony 3.3.3)
Upgrade symfony to 3.3.5 to fix the bug: symfony/symfony#23239
Upgrade symfony to 3.3.5 to fix the bug: symfony/symfony#23239
Upgrade symfony to 3.3.5 to fix the bug: symfony/symfony#23239
Upgrade symfony to 3.3.5 to fix the bug: symfony/symfony#23239
Upgrade symfony to 3.3.5 to fix the bug: symfony/symfony#23239
Upgrade symfony to 3.3.5 to fix the bug: symfony/symfony#23239
Upgrade symfony to 3.3.5 to fix the bug: symfony/symfony#23239
Upgrade symfony to 3.3.5 to fix the bug: symfony/symfony#23239
Upgrade symfony to 3.3.5 to fix the bug: symfony/symfony#23239
Upgrade symfony to 3.3.5 to fix the bug: symfony/symfony#23239
Upgrade symfony to 3.3.5 to fix the bug: symfony/symfony#23239
Previously, you either did not use controllers as services or you explicitly wired everything yourself. In case of a non-service controller the FrameworkBundle took care of calling
setContainer()
inside theinstantiateController()
method:With the new autowired controllers as services this is no longer happening as controllers do not need to be instantiated anymore (the container already returns fully built objects).