-
-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Improved the advantages/drawbacks of "controllers as services" #7495
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,17 +23,19 @@ These are the main **advantages** of defining controllers as services: | |
service container configuration. This is useful when developing reusable bundles; | ||
* Your controllers are more "sandboxed". By looking at the constructor arguments, | ||
it's easy to see what types of things this controller may or may not do; | ||
* If you're not passing some required dependencies or if you are injecting some | ||
non-existent services, you'll get errors during the container compilation | ||
instead of during runtime execution; | ||
* Since dependencies must be injected manually, it's more obvious when your | ||
controller is becoming too big (i.e. if you have many constructor arguments). | ||
|
||
These are the main **drawbacks** of defining controllers as services: | ||
|
||
* It takes more work to create the controllers because they don't have | ||
automatic access to the services or to the base controller shortcuts; | ||
* It takes more work to create the controllers and they become more verbose | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't really agree, controller's method should be as thin as possible and just calling services to do things to end by returning a response (so I've been told :). If services are there no need for shortcuts anymore. In the end you're just calling explicitly some methods, some would say "without magic" :D. Again the semantic does not look appropriate because from a DI point of view defining an object makes it a service, but orchestrate an action requires to call every needed services, hence the need to access them. The way we always used in Symfony is by making the controller class container aware, but defining explicitly the needed dependencies is not that different since the controller class is just virtual, what's truly needed is a locator and to group actions by scopes. The new locator feature is awesome for this, and Symfony is great for letting every ways of coding possible, because they are all powerful in their way, one just need to do and learn what he can and want to do with it. Personally I don't prefer one way or another, as long that it makes sense to do what you got to do. By letting everyone playing with it some ways may die naturally on the long run. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm sorry but I don't understand your comment. Let me show you why I wrote that phrase. For such a common thing as rendering a template, if you use the base controller, you do this: return $this->render('homepage.html.twig'); Just 1 short and beautiful PHP line. However, if you don't use that base controller, the equivalent code is this one: if (!$this->container->has('twig')) {
throw new \LogicException('...');
}
$response = new Response();
$response->setContent($this->container->get('twig')->render('homepage.html.twig'));
return $response; So, I think the previous phrase is correct: "It takes more work" ... and "they become more verbose". There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. But if the Twig environment is a hard (or safe) dependency, it could just be: return $this->twig->renderResponse('homepage.html.twig'); There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well, the working example would be: private $twig;
public function __construct(\Twig_Environment $twig)
{
$this->twig = $twig;
}
return $this->twig->renderResponse('homepage.html.twig'); So, again, "it takes more work" and "they become more verbose" 😄 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The class is but not the controllers in it :p |
||
because they don't have automatic access to the services and the base | ||
controller shortcuts; | ||
* The constructor of the controllers can rapidly become too complex because you | ||
must inject every single dependency needed by them; | ||
* The code of the controllers is more verbose because you can't use the shortcuts | ||
of the base controller and you must replace them with some lines of code. | ||
must inject every single dependency needed by them. | ||
|
||
The recommendation from the :doc:`best practices </best_practices/controllers>` | ||
is also valid for controllers defined as services: avoid putting your business | ||
|
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 is worth clarifying the semantic above, because technically this is not the constructor of a controller but of a class of controllers, in this way a Dunglas action is more a controller than the base controller class.