Dependency Injection

One of the most important features of the MVC design pattern is that it enables separation of concerns. Hence you can make your application’s components independent as much as possible. This is known as loose coupling, and it makes testing and maintenance of our application easier. Using Dependency Injection you can make you application’s components more loosely coupled.

Dependency Injection(DI) is a software design pattern that allow us to develop loosely coupled code. DI is a great way to reduce tight coupling between software components. DI also enables us to better manage future changes and other complexity in our software. The purpose of DI is to make code maintainable.

When classes are designed with DI in mind, they are more loosely coupled because they do not have direct, hard-coded dependencies on their collaborators. This follows the Dependency Inversion Principle, which states that "high level modules should not depend on low level modules; both should depend on abstractions." Instead of referencing specific implementations, classes request abstractions (typically interfaces) which are provided to them when the class is constructed.

Dependency Injection can be achieved in three ways, which are shown below.

  • Dependency Injection via Constructor Injection.
  • Dependency Injection via Method Injection.
  • Dependency Injection via Property Injection.

Constructor Injection :

Problem

Lets have three low level classes or modules.

//first Low level class   
class Sum    
{   
     public void calculate(int a, int b)
     {
          Console.WriteLine(a + b); 
     }
}

//second Low level class   
class Subtract    
{   
     public void calculate(int a, int b) 
     { 
          Console.WriteLine(a ‐ b);
     }  
}

//third Low level class
class Multiply 
{  
     public void calculate(int a, int b)   
     {   
         Console.WriteLine(a * b); 
     }   
}

Higher Level Module

class Calculation  
{   
      Sum s = null;   

     public void doCalculation(int a, int b) 
     { 
          s.calculate(a, b);      //here high level module depends on low level module   
      }  
     // for calling Subtract or Multiply we have to create instances and dependency is there
}   

What problem can we have?

This design is against the (DIP) Dependency Inversion Principle. Class Calculation depends on class Sum, which is a low level class. We can call “Subtract” and “Multiply” classes also like this, but we will use only one object at a time. Using this, we have to use all the objects at the same time, which we don’t want to use. For this, we have used the approach given below by Dependency Injection to achieve this.

Interface for Dependency Injection

//Interface for dependency Injection
interface ICalculate 
{   
    void calculate(int a, int b);  
}  

Low Level Modules

//first Low level class  
class Sum :ICalculate   
{   
     public void calculate(int a, int b)   
     {   
            Console.WriteLine(a + b);   
     }   
}   

//second Low level class      
class Subtract : ICalculate   
{   
     public void calculate(int a, int b)  
     {      
          Console.WriteLine(a ‐ b);  
     }   
}

//third Low level class   
class Multiply : ICalculate  
{   
     public void calculate(int a, int b)  
     {   
         Console.WriteLine(a * b);   
     }   
}  

High level Module

//high Level module   

class Calculation    
{   
          ICalculate cal= null;   
          //Constructor   
          //Dependency Injection via constructor   
          public Calculation(ICalculate iCal)   
          {   
               this.cal = iCal;   
          }   
          public void doCalculate(int a, int b)  
         {   
             cal.calculate(a, b);   
         }
}  

We will call the method, which we require, as shown below.

static void Main(string[] args)  
{   
            Sum s = new Sum();   
            Calculation calc= new Calculation(s);   
            s.calculate(6, 5);  
            Console.Read();    
}

Hence, there is no dependency now. Higher level module is not dependent on low level ones. We have done the Constructor Injection, while we are injecting the dependency in constructor only.

Method Injection

In this type of injection, the dependent object is injected, using the method of the class. In Constructor Injection, the dependent class uses the same concrete class for its all life time and if we have to pass some separate concrete class on each invocation of the method, at this moment, we have to pass the dependency in method only and not in constructor.

In Method Injection, we pass the object of the concrete class into the method of the dependent class.

Here, we pass the object of the class, which we want to use, which may be Sum, Subtract or Multiply into the method of Calculation class (method's name is doCalculate).We have to pass the object of the concrete class and the parameters used. The example of the Method Injection is given below.

interface ICalculate  
{   
        void calculate(int a, int b);   
}   

class Sum : ICalculate      
{   
        public void calculate(int a, int b)   
        {   
                Console.WriteLine(a + b);  
        }  
}   

//second Low level class   

class Subtract : ICalculate 
{   
        public void calculate(int a, int b)  
            {   
                Console.WriteLine(a ‐ b);   
        }   
}   

//third Low level class   

class Multiply : ICalculate   
{   
            public void calculate(int a, int b)   
            {   
                Console.WriteLine(a * b);   
            } 
}   

//high Level module   
class Calculation  
{   
    ICalculate cal= null;   
        //Constructor   
        //Dependency Injection via constructor   

            //Method Injection   
            public void doCalculate(ICalculate iCal, int a, int b)   
            {   
                this.cal = iCal;   
                cal.calculate(a, b);   
        }
}   

 class MethodInjection   
 {   
            static void Main(string[] args)  
            {   
                Sum s = new Sum();  
                Calculation calc= new Calculation();   
                calc.doCalculate(s, 5, 6);  
                Console.Read(); 
        }
  }

Here, we are passing the object of the Sum Class s and the parameters 5 and 6.

public void doCalculate(ICalculate iCal, int a, int b) 
{  
          this.cal = iCal;   
         cal.calculate(a, b);   
}  
//Calling Or Intializing   
Sum s = new Sum();   
Calculation calc = new Calculation();   
calc.doCalculate(s, 5, 6);  

If we want to use any other class other than Sum, we can pass the object of that class here.

Property Injection

As we have seen in the two cases, mentioned above, In Constructor Injection Dependent class, we will use one concrete class for the entire lifetime and the in Method Injection, we will pass the object of the concrete class into the method of the dependent class. In a case, when both the concrete classes and the high level modules are in different places (modules), how can we achieve the Dependency Injection? This brings us to the part of Property Injection. In Property Injection, we will have a setter property in the High Level Module/ Dependent class and we will pass the object of the concrete class via this setter property. In this type, the setter property of the dependent class will take the object of the concrete class and pass it to the Interface used by the class.

interface ICalculate   
{  
    void calculate(int a, int b);  
}  

class Sum : ICalculate  
{   
        public void calculate(int a, int b)   
            {          
                 Console.WriteLine(a + b);  
            }   
 }   

//second Low level class  

class Subtract : ICalculate   
{   
        public void calculate(int a, int b)   
            {   
                Console.WriteLine(a ‐ b);   
        }   
}  

//third Low level class   
class Multiply : ICalculate   
{   
        public void calculate(int a, int b)   
            {   
                Console.WriteLine(a * b);   
            }   
}  

//high Level module   
class Calculation  
{   
            ICalculate cal= null;   
        //Property Setter where this property will be set by Object of the class   
        public ICalculate Cal
        {  
                 get  
                 {   
                return cal;  
                 }   
                 set   
                 {   
                cal= value;   
                 }   
        }   

        //Method Injection   
            public void doCalculate(int a, int b)   
            {   
                cal.calculate(a, b);   
            }   
} 

class PropertyInjection   
{   
        static void Main(string[] args)   
        {  
        Sum s = new Sum();  
            Calculation calc = new Calculation();  
            calc.Cal = s;   
            calc.doCalculate(3, 4);   
            Console.Read();   
            }
}

Property Injection is also called Setter Injection.

Hope you understood it better : )

Thank you

Your comment

*

*