What is Dependency Injection?

What is Dependency Injection?

 
Dependency Injection is a software design pattern for injecting dependencies. It helps your code in resolving dependencies by injecting the dependency to a dependent object; Making your code more decoupled, modular and flexible. Dependency Injection is a commonly used by frameworks that deal with a huge amount of dependencies. You may already have used it in your codes before even realizing it.

Below is an overview for programmers that needs to know what Dependency Injection really is, and how does it work; This is not a beginner’s guide for dependency injection. I will just show you the concept behind dependency injection. PHP is the language used in the examples below.

Dependency Injection vs. Inversion of Control

We often see Dependency Injection along side with Inversion of Control in most features listed on frameworks that we often mistake them as one; Dependency Injection is not Inversion of Control. It is a type of Inversion of Control that is commonly used along with other types such as the Service Locator and Factory Patterns.

 

How does Dependency Injection work?

The snippets below shows what a common dependency looks like. We often pull the dependency into the class we are defining.

 


class GuideDog {

    protected $breed;

    public function setBreed($breed) {
        $this->breed = $breed;
    }

    public function getBreed() {
        return $this->breed;
    }

    public function leadBlind() {
        // some stuff to lead the blind guy
    }

    public function bark() {
        // arf arf..
    }
}

class BlindGuy {

    protected $guideDog;

    public function __construct() {
        $this->guideDog = new GuideDog('GoldenRetriever');
    }
}

 
The BlindGuy is dependent on the GuideDog; Every time you instantiate a BlindGuy object, a GuideDog object with a breed of a GoldenRetriever will be loaded too. Hence, “pulling” the GuideDog dependency into the BlindGuy class.

What if we need to specify a different breed of GuideDog?
 


class BlindGuy {

    protected $guideDog;

    public function __construct(GuideDog $guideDog) {
        $this->guideDog = $guideDog;
    }
}

$germanShepherdGuide = new GuideDog()
$germanShepherdGuide->setBreed('GermanShepherd');
$blindPeter = new BlindGuy($germanShepherdGuide);

 

In the snippet above, we moved the GuideDog dependency as a constructor parameter. We can now specify the breed of the GuideDog every time we create a BlindGuy. We are now “injecting” the GuideDog dependency into the BlindGuy class thus the “Inversion of Control”.

 
[adsense]

 

More flexibility you say?

Although using the GuideDog as a constructor parameter may seem to be a good idea, the BlindGuy is still dependent on the GuideDog class. This means that every time a developer will use your BlindGuy class, he still needs to use the specific GuideDog class you defined.

Let’s say another developer named Stewie wanted to use his TalkingGuideDog class for your BlindGuy class. You may be thinking..

“Oh, I’ll just ‘extend’ the GuideDog class so I will inherit all its properties and methods! Take that blog poster you!”

Yes, it will work but in some languages like PHP, you will be sacrificing your single opportunity in having a parent class; Remember that you can only extend only one class. To solve this problem, we are going to use Interfaces. By defining a GuideDogInterface, Stewie can now create a GuideDog dependency for your BlindGuy class without needing your own GuideDog class; Stewie will just need to follow the rules the GuideDogInterface has set for him.

Why would a guide dog that can “talk()” still need to “bark()”?


interface GuideDogInterface {

    public function setBreed($breed);

    public function getBreed();

    public function leadBlind();

}

class TalkingGuideDog implements GuideDogInterface {

    public function setBreed($breed) {
        $this->breed = $breed;
    }

    public function getBreed() {
        return $this->breed;
    }

    public function leadBlind() {
        // some stuff to lead the blind guy
    }

    public function talk() {
        // this dog talks about the importance of life..
    }
}

class BlindGuy {

    protected $guideDog;

    public function __construct(GuideDogInterface $guideDog) {
        $this->guideDog = $guideDog;
    }
}

$brian = new TalkingGuideDog();
$brian->setBreed('WhiteLabrador');

$blindPeter = new BlindGuy($brian);

 

The GuideDog dependency can now have implementations from different developers in accordance to what the GuideDogInterface has set for them; Making your code more decoupled and flexible.

There different types of dependency injection all of which are used to invert the control from the dependent object into the dependency. Different frameworks and different programming languages may have different ways of injecting dependencies that may confuse you; You just need to understand the concept behind it.

For more comprehensive details about Dependency Injection, check out the links below.

2 thoughts on “What is Dependency Injection?”

Leave a Reply

%d bloggers like this: