Dependency Injection Simplified

A lot is being said and written about Dependency Injection(DI) these days. Its amazing how most of these current literature make DI sound so complicated. In reality though the concept is really simple. Powerful but yet simple. DI is based on one of the SOLID principles called the Dependency Inversion Principle (DIP) propagated by Uncle Bob. The principle states:


HIGH LEVEL MODULES SHOULD NOT DEPEND UPON LOW LEVEL MODULES. BOTH SHOULD DEPEND UPON ABSTRACTIONS.
ABSTRACTION SHOULD NOT DEPEND UPON DETAILS. DETAILS SHOULD DEPEND UPON ABSTRACTION.

Let’s try to understand this with an example. As I write this post on a Sunday evening enjoying a Four-cheese pizza slice (yummy!), all I can think of for an example is pizzas. Let’s assume a class called PizzaStore, which has a specialty in Grilled Chicken pizzas. Hence it sells only this Grilled Chicken pizza. Let’s call this class as ChickenPizza.

public class PizzaStore
{
    public void CreatePizza()
    {
        ChickenPizza pizza = new ChickenPizza();
        pizza.Prepare();
    }
}

Here the PizzaStore class is said to be the higher-level class and ChickenPizza class is the lower-level class. Hence we have a high-level class depend upon the low- level class. But so far, this is perfectly fine and acceptable as there is just one type of pizza to prepare.

Time passes, and our little PizzaStore becomes more popular. The business grows and so the demands. Its time that they add some more veriety to the kind of pizzas they sell. The Pizza store introduces a new pizza – the famous Chicago Deep Dish pizza. Lets this be called the DeepDishPizza.

This will require the high-level PizzaStore class to change a little to accomodate this new low-level DeepDishPizza class.

public class PizzaStore
{
   public void CreatePizza(string pizzaType)
   {
      if (pizzaType == "DeepDishPizza")
      {
          DeepDishPizza pizza = new DeepDishPizza();
          pizza.Prepare();
      }
      else
      {
          ChickenPizza pizza = new ChickenPizza();
          pizza.Prepare();
      }
   }
}

This means every time a new Pizza type is introduced, the PizzaStore class will need to change. That is, the high-level class will need to change if a low level class changes. With increase in number of these pizza classes the coupling will keep on increasing. Plugging in a new type of pizza will not very easy, even for this overly simplified PizzaStore.

Let’s try analyze if DI can come to the rescue as far as our little PizzaStore is concerned.

In order to implement DI here, we will need to abstract out the commonalities of these pizza classes in an abstract class called Pizza class.

public abstract class Pizza
{
   public virtual void Prepare();
}

Let all the pizza classes inherit from this class and implement their own version of Prepare() method.

public class ChickenPizza: Pizza
{
   public override void Prepare()
   {
      ...
   }
}

 


public class DeepDishPizza: Pizza
{
   public override void Prepare()
   {
      ...
   }
}

And the PizzaStore class will work only with the abstraction of Pizza

Public class PizzaStore
{
   private Pizza _pizza;
   public PizzaStore(Pizza pizza)
   {
       _pizza = pizza;
   }
   public void CreatePizza()
   {
       _pizza.Prepare();
   }
}

This technique of passing (or injecting) the instance (Dependency) on to the depending class (PizzaStore) class is called Dependency Injection.

The technique is simple but very powerful to achieve the ultimate design goal – “Loose Coupling”.

About these ads

2 thoughts on “Dependency Injection Simplified

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s