Lesson 4
Exploring Dependency Injection in Symfony
Exploring Dependency Injection in Symfony

Welcome back! In previous lessons, we've covered key Symfony concepts such as creating controllers, defining routes, and utilizing services. In the last lesson, we delved into Services and had a brief introduction to Dependency Injection, both of which are essential for building modular and maintainable Symfony applications.

This time, we will delve deeper into Dependency Injection and explore its extensive use in Symfony. Our primary goal is to build a feature that compares dog breeds utilizing dependency injection. By the end of this lesson, you'll have a better understanding of how to configure services and inject them into a controller.

Understanding Dependency Injection

Let's start with a brief definition. Dependency Injection is a technique where an object (such as a controller) receives the tools it needs (its dependencies) from an external source rather than creating them itself. This promotes loose coupling and makes the code easier to test and maintain.

In Symfony, dependency injection is managed by the service container. The service container keeps track of all the services and their dependencies and automatically injects the required services when needed.

For example, if a controller needs to compare dog breeds using two services, CorgiService and HuskyService, instead of creating these services inside the controller, we would inject them via the constructor. This is both cleaner and makes our application more modular.

Creating the CorgiService

First, let's create the CorgiService that our controller will use. This service will provide the breed name of a Corgi dog.

Here is the code for the CorgiService:

php
1<?php 2 3namespace App\Service; 4 5class CorgiService 6{ 7 public function getBreed(): string 8 { 9 return 'Corgi'; 10 } 11}

The CorgiService class has a method called getBreed that returns the string 'Corgi'.

Creating the HuskyService

Next, let's create the HuskyService, which will provide the breed name of a Husky dog.

Here is the code for the HuskyService:

php
1<?php 2 3namespace App\Service; 4 5class HuskyService 6{ 7 public function getBreed(): string 8 { 9 return 'Husky'; 10 } 11}

Similarly, the HuskyService class also has a getBreed method, which returns the string 'Husky'.

Setting Up the Controller

Now let's set up a controller to compare dog breeds. We'll define the DogController and use dependency injection to access both CorgiService and HuskyService.

Here is the code for our controller:

php
1<?php 2 3namespace App\Controller; 4 5use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; 6use Symfony\Component\HttpFoundation\Response; 7use App\Service\CorgiService; 8use App\Service\HuskyService; 9 10class DogController extends AbstractController 11{ 12 private $corgiService; 13 private $huskyService; 14 15 public function __construct(CorgiService $corgiService, HuskyService $huskyService) 16 { 17 $this->corgiService = $corgiService; 18 $this->huskyService = $huskyService; 19 } 20 21 public function compareDogs(): Response 22 { 23 $comparison = sprintf( 24 'Comparing breeds: %s vs %s', 25 $this->corgiService->getBreed(), 26 $this->huskyService->getBreed() 27 ); 28 29 return $this->render('comparison.html.twig', ['message' => $comparison]); 30 } 31}

In the DogController class, we inject CorgiService and HuskyService through its constructor, allowing the controller to access these services without creating them internally.

The compareDogs method uses the getBreed method from both services to generate a comparison message, which is then rendered using a Twig template.

This structure ensures that the controller is clean, focusing solely on orchestrating the logic rather than creating dependencies.

Summary and Next Steps

In this lesson, we covered the following key concepts:

  • The importance and benefits of dependency injection.
  • How to create and utilize services in Symfony.
  • Setting up a controller in Symfony with dependency injection.

By now, you should have a good understanding of how to use dependency injection to manage dependencies in Symfony, making your application more modular and maintainable. Up next, you'll get hands-on practice through exercises that will reinforce these concepts.

Good luck and happy coding!

Enjoy this lesson? Now it's time to practice with Cosmo!
Practice is how you turn knowledge into actual skills.