Non-Autowireable 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 SubscribeIn the last chapter, we autowired a non-autowireable argument. This time, let's try to autowire an non-autowireable service. But before we do that, we need to find a non-autowireable service. To do that, at your terminal, run:
bin/console debug:container
If you think this Twig service can't be autowired since it's just an ID, think again. If we scroll up, we see Twig\Environment
. This is an alias for our Twig service. Conversely, twig.command.debug
is not autowireable. This is the service that powers the debug:twig
command we used in previous chapters. When we run that in our terminal,
bin/console debug:twig
it gives us a list of all of the Twig filters and functions available in our app. That means, even though it's kind of odd, we can grab this service and use it directly. Good to know!
Back over here, in homepage()
, typehint DebugCommand
(the one from Twig) and let's call this $twigDebugCommand
.
// ... lines 1 - 5 | |
use Symfony\Bridge\Twig\Command\DebugCommand; | |
// ... lines 7 - 15 | |
class MainController extends AbstractController | |
{ | |
// ... line 18 | |
public function homepage( | |
// ... lines 20 - 22 | |
DebugCommand $twigDebugCommand, | |
): Response { | |
// ... lines 25 - 38 | |
} | |
} |
The Autowire Attribute
If we head back to our browser and refresh... we get an error:
Cannot autowire argument
$twigDebugCommand
ofApp\Controller\MainController::homepage()
If you guessed that we'll need to use the attribute above the argument like we did with our parameters, you're correct, but the syntax for services looks a little different. Over here, above our DebugCommand
, add a new attribute - #[Autowire()]
. Inside, we'll set service
to the service name. I'll cheat and copy the exact service name from the list in our terminal.
// ... lines 1 - 7 | |
use Symfony\Component\DependencyInjection\Attribute\Autowire; | |
// ... lines 9 - 15 | |
class MainController extends AbstractController | |
{ | |
// ... line 18 | |
public function homepage( | |
// ... lines 20 - 22 | |
#[Autowire(service: 'twig.command.debug')] | |
DebugCommand $twigDebugCommand, | |
): Response { | |
// ... lines 26 - 39 | |
} | |
} |
Okay, if we head back and refresh the homepage again... it was successfully autowired. Nice!
Using the Autowired Service
All right, let's see if we can run that command. Below Response
, write $twigDebugCommand->run()
. The first argument should be an input, so we can say new ArrayInput
. The second argument should be the output that we'll use below, but before we do that, we need to create an output variable. Above, write $output = new BufferedOutput()
. Now we can add $output
as our second argument here. Okay, our editor is happy, so finally, below, let's dd($output)
. If we head to our browser and refresh... dang... error. It looks like we need to pass an empty array to the ArrayInput()
class. If we do that and refresh again... boom! We get a list of functions and filters. It works. This was just an example, so we can get rid of that code, but the key thing to remember is that, even if something isn't autowireable by default, you can make it autowireable with an #[Autowire]
attribute, regardless of whether you need a service or a parameter.
Next: Let's talk about environment variables and the purpose of the .env
file we saw earlier. We'll also see how we can leverage them in our app so it behaves differently in certain environments.
Cool!