Controllers as Services
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.
With a Subscription, click any sentence in the script to jump to that part of the video!
Login SubscribeThere is one other piece of auto-registration code in the new services.yml file for Symfony 3.3 involving the Controller/
directory. Copy that!
Then, paste it in our file:
// ... lines 1 - 8 | |
services: | |
// ... lines 10 - 16 | |
AppBundle\: | |
// ... lines 18 - 22 | |
# controllers are imported separately to make sure they're public | |
# and have a tag that allows actions to type-hint services | |
AppBundle\Controller\: | |
resource: '../../src/AppBundle/Controller' | |
public: true | |
tags: ['controller.service_arguments'] | |
// ... lines 29 - 57 |
This auto-registers each class in src/AppBundle/Controller
as a service... which was already done above:
// ... lines 1 - 8 | |
services: | |
// ... lines 10 - 14 | |
# makes classes in src/AppBundle available to be used as services | |
# this creates a service per class whose id is the fully-qualified class name | |
AppBundle\: | |
resource: '../../src/AppBundle/*' | |
# you can exclude directories or files | |
# but if a service is unused, it's removed anyway | |
exclude: '../../src/AppBundle/{Entity,Repository}' | |
# controllers are imported separately to make sure they're public | |
# and have a tag that allows actions to type-hint services | |
AppBundle\Controller\: | |
// ... lines 26 - 57 |
This overrides those services to make sure that anything in Controller/
is public and has this very special tag. In Symfony 3.3 - controllers are the one service that must be public. And the tag gives us a special controller argument autowiring super power that we'll see soon.
Controllers are Services!?
But wait, our controllers are services!? Yes! In Symfony 3.3, we recommend that all of your controllers be registered as a service. And it's so awesome! You can still use all of your existing tricks. You can still extend Symfony's base Controller
class and use its shortcuts. You can even still fetch public services directly from the container. But now, you can also use proper dependency injection if you want to. And, as long as your service's id is the class name, all of the existing routing config formats will automatically know to use your service. In other words, this just works.
Removing Unnecessary Services
Now that we're auto-registering each class as a service, we can remove these two services:
// ... lines 1 - 8 | |
services: | |
// ... lines 10 - 32 | |
AppBundle\Twig\MarkdownExtension: | |
#arguments: ['@app.markdown_transformer'] | |
AppBundle\Security\LoginFormAuthenticator: ~ | |
// ... lines 37 - 57 |
They're still being registered, but since we don't need to add any further configuration, they're redundant!
Woohoo! And when we refresh our app, everything still works! Controllers as services with four lines of code!
Hello, I'm trying to call an action from a controller to another controller.
So I've UserController and "getRegistrationNumberAction(Event $event)" and from EventController I call
$number= $this->get(UserController::class)->getRegistrationNumberAction($workEvent);
The error appear here:
$em= $this->getDoctrine()->getManager();
and the error is: Call to a member function has() on null
I've modified services.yml with new symfony configurations (autowire, _defaults, etc) so I can't understand what is wrong. Can you help me?
PS: If I try to dump $this->get(UserController::class) it dump null.
Thanks