Dependency Injection In C#

Dependency Injection

Dependency Injection mainly reduces the tight coupling between the classes. Dependency Injection moves the abstraction binding out of the class or higher level modules. By Dependency Injection, we can achieve the process of removing the dependency of low level modules from higher level modules. 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.

Dependency Injection via Constructor Injection

Problem

Lets have three low level classes or modules.

  1. //first Low level class  
  2.     class Sum   
  3.     {  
  4.         public void func(int a, int b)  
  5.         {  
  6.   
  7.             //return a + b;  
  8.             Console.WriteLine(a + b);  
  9.         }  
  10.   
  11.     }  
  12.   
  13.     //second Low level class  
  14.     class Subtract   
  15.     {  
  16.         public void func(int a, int b)  
  17.         {  
  18.   
  19.             Console.WriteLine(a - b);  
  20.         }  
  21.     }  
  22.   
  23.     //third Low level class  
  24.     class Multiple   
  25.     {  
  26.         public void func(int a, int b)  
  27.         {  
  28.   
  29.             Console.WriteLine(a * b);  
  30.         }  
  31.     }   

Higher Level Module

  1. class HighlevelModule  
  2.     {  
  3.         //DependencyInterface Action = null;  
  4.         Sum s = null;  
  5.         public void funcWrite(int a, int b)  
  6.         {  
  7.             s.func(a, b);      //here hig level module depends on low level module  
  8.         }  
  9.         // for calling sub or mul we have to create instances and dependency is there  
  10.     }   

What problem can we have?

This design is against the DIP Dependency Inversion Principle. Class HighlevelModule depends on class Sum, which is a low level class. We can call “Subtract” and “mul” 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 
  1. //Interface for dependency Injection  
  2.   interface IDependencyInterface  
  3.   {  
  4.       void func(int a, int b);  
  5.   }   
Low Level Modules
  1. //first Low level class  
  2.     class Sum :IDependencyInterface  
  3.     {  
  4.         public void func(int a, int b)  
  5.         {  
  6.   
  7.             //return a + b;  
  8.             Console.WriteLine(a + b);  
  9.         }  
  10.   
  11.     }  
  12.   
  13.         //second Low level class  
  14.     class Subtract : IDependencyInterface  
  15.     {  
  16.         public void func(int a, int b)  
  17.         {  
  18.   
  19.             Console.WriteLine(a - b);  
  20.         }  
  21.     }  
  22.   
  23.         //third Low level class  
  24.     class Multiple : IDependencyInterface  
  25.     {  
  26.         public void func(int a, int b)  
  27.         {  
  28.   
  29.             Console.WriteLine(a * b);  
  30.         }  
  31.     }  
High level Module
  1. //high Level module  
  2.     class HighlevelModule  
  3.     {  
  4.         IDependencyInterface action = null;  
  5.        // Sum s = null;  
  6.         //Constructor  
  7.         //Dependency Injection via constructor  
  8.         public HighlevelModule(IDependencyInterface act)  
  9.         {  
  10.             this.action = act;  
  11.   
  12.         }  
  13.   
  14.         public void Actionfunc(int a, int b)  
  15.         {  
  16.             action.func(a, b);  
  17.         }  
  18.   
  19.         
  20.     }  

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

  1. static void Main(string[] args)  
  2.         {  
  3.   
  4.             Sum s = new Sum();  
  5.             HighlevelModule high = new HighlevelModule(s);  
  6.             s.func(6, 5);  
  7.             Console.Read();   
  8.         }   

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.

Output
 
 
Dependency Injection via 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 Multiple into the method of HighlevelModuleM class (method's name is Actionfunc).We have to pass the object of the concrete class and the parameters used.

The example of the Method Injection is given below.
  1. class MethodInjection  
  2.     {  
  3.         static void Main(string[] args)  
  4.         {  
  5.   
  6.             Sum s = new Sum();  
  7.             HighlevelModuleM high = new HighlevelModuleM();  
  8.             high.Actionfunc(s, 5, 6);  
  9.             //s.Actionfunc  
  10.             //s.funct(6, 5);  
  11.             Console.Read();  
  12.         }  
  13.     }  
  14.   
  15.   
  16.     //high Level module  
  17.     class HighlevelModuleM  
  18.     {  
  19.         IDependencyInterface actionM = null;  
  20.         // Sum s = null;  
  21.         //Constructor  
  22.         //Dependency Injection via constructor  
  23.         //public HighlevelModule(IDependencyInterface act)  
  24.         //{  
  25.         //    this.action = act;  
  26.   
  27.         //}  
  28.         //Method Injection  
  29.         public void Actionfunc(IDependencyInterface act, int a, int b)  
  30.         {  
  31.             this.actionM = act;  
  32.             actionM.funct(a, b);  
  33.   
  34.         }  
  35.   
  36.   
  37.   
  38.     }  
  39.   
  40.   
  41.   
  42.     interface IDependencyInterface  
  43.     {  
  44.         void funct(int a, int b);  
  45.     }  
  46.   
  47.     class Sum : IDependencyInterface  
  48.     {  
  49.         public void funct(int a, int b)  
  50.         {  
  51.   
  52.             //return a + b;  
  53.             Console.WriteLine(a + b);  
  54.         }  
  55.   
  56.     }  
  57.   
  58.     //second Low level class  
  59.     class Subtract : IDependencyInterface  
  60.     {  
  61.         public void funct(int a, int b)  
  62.         {  
  63.   
  64.             Console.WriteLine(a - b);  
  65.         }  
  66.     }  
  67.   
  68.     //third Low level class  
  69.     class Multiple : IDependencyInterface  
  70.     {  
  71.         public void funct(int a, int b)  
  72.         {  
  73.   
  74.             Console.WriteLine(a * b);  
  75.         }  
  76.     }   
Here, we are passing the object of the Sum Class s and the parameters 5 and 6.
  1.       public void Actionfunc(IDependencyInterface act, int a, int b)  
  2.       {  
  3.           this.actionM = act;  
  4.           actionM.funct(a, b);  
  5.   
  6.       }  
  7.   
  8. //Calling Or Intializing  
  9. Sum s = new Sum();  
  10.           HighlevelModuleM high = new HighlevelModuleM();  
  11.           high.Actionfunc(s, 5, 6);  
If we want to use any other class other than Sum, we can pass the object of that class here.
 
Output


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 life time 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.

  1. class PropertyInjection  
  2.     {  
  3.         static void Main(string[] args)  
  4.         {  
  5.   
  6.             SumP s = new SumP();  
  7.             HighlevelModuleP high = new HighlevelModuleP();  
  8.             high.ActionP = s;  
  9.             high.Actionfunc(3, 4);  
  10.             Console.Read();  
  11.         }  
  12.     }  
  13.   
  14.     //high Level module  
  15.     class HighlevelModuleP  
  16.     {  
  17.         IDependencyInterfaceP actionP = null;  
  18.   
  19.         //Propert Setter where this property will be set by Object of the class  
  20.         public IDependencyInterfaceP ActionP  
  21.         {  
  22.             get  
  23.             {  
  24.                 return actionP;  
  25.             }  
  26.             set  
  27.             {  
  28.                 actionP = value;  
  29.             }  
  30.         }  
  31.   
  32.         //Method Injection  
  33.         public void Actionfunc(int a, int b)  
  34.         {  
  35.             actionP.functP(a, b);  
  36.   
  37.         }  
  38.   
  39.   
  40.   
  41.     }  
  42.   
  43.   
  44.   
  45.     interface IDependencyInterfaceP  
  46.     {  
  47.         void functP(int a, int b);  
  48.     }  
  49.   
  50.     class SumP : IDependencyInterfaceP  
  51.     {  
  52.         public void functP(int a, int b)  
  53.         {  
  54.   
  55.             //return a + b;  
  56.             Console.WriteLine(a + b);  
  57.         }  
  58.   
  59.     }  
  60.   
  61.     //second Low level class  
  62.     class SubtractP : IDependencyInterfaceP  
  63.     {  
  64.         public void functP(int a, int b)  
  65.         {  
  66.   
  67.             Console.WriteLine(a - b);  
  68.         }  
  69.     }  
  70.   
  71.     //third Low level class  
  72.     class MultipleP : IDependencyInterfaceP  
  73.     {  
  74.         public void functP(int a, int b)  
  75.         {  
  76.   
  77.             Console.WriteLine(a * b);  
  78.         }  
  79.     }  

The output of this will be, as shown below.

 

Property Injection is also called Setter Injection.
 
Attached is the source code in C# for Dependency injection (Constructor, Method and Property Injection).
Ebook Download
View all
Learn
View all