Dependency Injection and Inversion of Control

In this article, I am going to explore the principle of Dependency Injection, in a very simple way that is very easy to understand. We will take an example from our daily programming practice.

You can find this original article on my blog, here.

Dependency Injection is a way to resolve tight coupling and create loosely coupled classes.

e.g. 

  1. public class A  
  2.    {  
  3.        public B b { get; set; }  
  4.    }  
  5. public class B  
  6.    {  
  7.    }   

This is tight coupling or dependency, or we can say that class A is tightly coupled with class B.

Let’s see what dependency is. What WIKI says about 'Dependency

"Dependency (computer science) or coupling is a state in which one object uses a function of another object."

Let's now learn, what Dependency Injection is,

"Dependency Injection is a way to create object dependencies outside of the class that uses it."

You inject them from the outside, and take the control of their creation away from the inside of the class.

For example, suppose we have an order class which has some methods to save the order.

  1. public class Order  
  2.   {  
  3.       public void SaveOrder()  
  4.       {  
  5.           // order saving code here....  
  6.       }  
  7.   }   

Suppose, the order class needs to send some notification also, notifying that the order has got placed or something. So, we need to modify the order class.

  1. public class Order  
  2.   {  
  3.       Notify ObjNotify;   
  4.       public void SaveOrder()  
  5.       {  
  6.           // some order saving code here.....  
  7.           ObjNotify = new Notify();    
  8.           ObjNotify.SendNotification(); // send some notification message or mail  
  9.       }  
  10.   }  
  11.   public class Notify  
  12.   {  
  13.       public void SendNotification()  
  14.       {  
  15.           // some code here  
  16.       }  
  17.   }   

There is a problem in our SaveOrder method. So, what we are doing wrong here?

Notify ObjNotify = new Notify(); this line.

We are creating an object of the Notify class inside our Order class, which means the Order class is dependent on the Notify class. This is called "dependency or tight coupling" since we are creating object dependency inside the Order class.

The Dependency Injection principle provides a solution to this issue. The dependency principle says, "Create object dependencies outside of the class and inject it in your class". That's it ! Looks so simple...

Example

Let’s modify Order class.

  1. public class Order  
  2.   {  
  3.       Notify ObjNotify;   
  4.       //Constructor injection  
  5.       Public Order(Notify ObjNotifyParam) //inject Notify object as contrt parameter                                                                                 
  6.       {  
  7.          this.ObjNotify= ObjNotifyParam;  
  8.       }  
  9.       public void SaveOrder()  
  10.       {  
  11.           // some order saving code here.....  
  12.           ObjNotify.SendNotification(); // send some notification message or mail  
  13.       }  
  14.   }   

Consuming Order class at client.

  1. Notify ObjNotify = new Notify(); // create object of the Notify class  
  2.  Order ObjOrder = new Order(ObjNotify); //create Order class object & inject notify ob   

Now, we are creating Notify object outside of the Order class and when we instantiate order class, we are injecting the Notify object through Order class constructor.

Is it called Dependency Injection ?

We can say "Yes". We have injected the object dependency from outside the Order call so it is the dependency injection principle. Or, we can say that we have implemented DI.

But still, our Order class is depending on the Notify class, so I think we need to do something more.

Now, another principle comes in the picture, that is, ‘Inversion Of Control’. Both the principles come together for good application design.

Let’s see what WIKI says about IoC

"Inversion of Control (IoC) is a design principle in which custom-written portions of a computer program receive the flow of control from a generic framework.’ Bit difficult to me to understand."

OK. So, in simple words, IoC enforces the DI principle for your components to make them loosely coupled and allow code to abstractions.

Let’s modify our class. We will remove Notify dependency from our Order class constructor to make it work with abstraction. So, create an interface 

  1. public interface INotify  
  2.    {  
  3.        void SendNotification();  
  4.    }    

And our Notify class implements this INotify interface.

Let’s change our Notify class.

  1. public class Notify : INotify  
  2.    {  
  3.        public void SendNotification()  
  4.        {  
  5.          // some code here  
  6.        }  
  7.    }   

Modify your Order class for abstraction.

  1. public class Order  
  2.     {  
  3.         INotify ObjNotify;  
  4.         //Constructor injection  
  5.         public Order(INotify ObjNotifyParam) //inject INotify reference Notify object  
  6.         {                                    //as constructor parameter  
  7.             this.ObjNotify = ObjNotifyParam;  
  8.         }  
  9.         public void SaveOrder()  
  10.         {  
  11.             // some order saving code here.....  
  12.             ObjNotify.SendNotification(); // send some notification message or mail  
  13.         }  
  14.     }   

Consuming Order class at client.

  1. // take INotify reference & create object of the  Notify class  
  2. INotify ObjNotify = new Notify();  
  3. //create Order class object & inject notify object  
  4. Order ObjOrder = new Order(ObjNotify);   

That’s it. It is our fully testified design for DI and IoC.

Benefits of the DI

  • Loose coupling
  • Centralize control
  • Easily testable
  • Easily extendable
Ebook Download
View all
Learn
View all