Login to bookmark this video
Buy Access to Course
12.

Non-Autowireable 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

In 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.

41 lines | src/Controller/MainController.php
// ... 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 of App\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.

42 lines | src/Controller/MainController.php
// ... 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.