Buy Access to Course
06.

Controllers as Services

Share this awesome video!

|

Keep on Learning!

With a Subscription, click any sentence in the script to jump to that part of the video!

Login Subscribe

There 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:

57 lines | app/config/services.yml
// ... 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:

57 lines | app/config/services.yml
// ... 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:

57 lines | app/config/services.yml
// ... 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!