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.
-
- class Sum
- {
- public void func(int a, int b)
- {
-
-
- Console.WriteLine(a + b);
- }
-
- }
-
-
- class Subtract
- {
- public void func(int a, int b)
- {
-
- Console.WriteLine(a - b);
- }
- }
-
-
- class Multiple
- {
- public void func(int a, int b)
- {
-
- Console.WriteLine(a * b);
- }
- }
Higher Level Module
- class HighlevelModule
- {
-
- Sum s = null;
- public void funcWrite(int a, int b)
- {
- s.func(a, b);
- }
-
- }
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
-
- interface IDependencyInterface
- {
- void func(int a, int b);
- }
Low Level Modules
-
- class Sum :IDependencyInterface
- {
- public void func(int a, int b)
- {
-
-
- Console.WriteLine(a + b);
- }
-
- }
-
-
- class Subtract : IDependencyInterface
- {
- public void func(int a, int b)
- {
-
- Console.WriteLine(a - b);
- }
- }
-
-
- class Multiple : IDependencyInterface
- {
- public void func(int a, int b)
- {
-
- Console.WriteLine(a * b);
- }
- }
High level Module
-
- class HighlevelModule
- {
- IDependencyInterface action = null;
-
-
-
- public HighlevelModule(IDependencyInterface act)
- {
- this.action = act;
-
- }
-
- public void Actionfunc(int a, int b)
- {
- action.func(a, b);
- }
-
-
- }
We will call the method, which we require, as shown below.
- static void Main(string[] args)
- {
-
- Sum s = new Sum();
- HighlevelModule high = new HighlevelModule(s);
- s.func(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.
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.
- class MethodInjection
- {
- static void Main(string[] args)
- {
-
- Sum s = new Sum();
- HighlevelModuleM high = new HighlevelModuleM();
- high.Actionfunc(s, 5, 6);
-
-
- Console.Read();
- }
- }
-
-
-
- class HighlevelModuleM
- {
- IDependencyInterface actionM = null;
-
-
-
-
-
-
-
-
-
- public void Actionfunc(IDependencyInterface act, int a, int b)
- {
- this.actionM = act;
- actionM.funct(a, b);
-
- }
-
-
-
- }
-
-
-
- interface IDependencyInterface
- {
- void funct(int a, int b);
- }
-
- class Sum : IDependencyInterface
- {
- public void funct(int a, int b)
- {
-
-
- Console.WriteLine(a + b);
- }
-
- }
-
-
- class Subtract : IDependencyInterface
- {
- public void funct(int a, int b)
- {
-
- Console.WriteLine(a - b);
- }
- }
-
-
- class Multiple : IDependencyInterface
- {
- public void funct(int a, int b)
- {
-
- Console.WriteLine(a * b);
- }
- }
Here, we are passing the object of the Sum Class s and the parameters 5 and 6.
- public void Actionfunc(IDependencyInterface act, int a, int b)
- {
- this.actionM = act;
- actionM.funct(a, b);
-
- }
-
- //Calling Or Intializing
- Sum s = new Sum();
- HighlevelModuleM high = new HighlevelModuleM();
- 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
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.
- class PropertyInjection
- {
- static void Main(string[] args)
- {
-
- SumP s = new SumP();
- HighlevelModuleP high = new HighlevelModuleP();
- high.ActionP = s;
- high.Actionfunc(3, 4);
- Console.Read();
- }
- }
-
-
- class HighlevelModuleP
- {
- IDependencyInterfaceP actionP = null;
-
-
- public IDependencyInterfaceP ActionP
- {
- get
- {
- return actionP;
- }
- set
- {
- actionP = value;
- }
- }
-
-
- public void Actionfunc(int a, int b)
- {
- actionP.functP(a, b);
-
- }
-
-
-
- }
-
-
-
- interface IDependencyInterfaceP
- {
- void functP(int a, int b);
- }
-
- class SumP : IDependencyInterfaceP
- {
- public void functP(int a, int b)
- {
-
-
- Console.WriteLine(a + b);
- }
-
- }
-
-
- class SubtractP : IDependencyInterfaceP
- {
- public void functP(int a, int b)
- {
-
- Console.WriteLine(a - b);
- }
- }
-
-
- class MultipleP : IDependencyInterfaceP
- {
- public void functP(int a, int b)
- {
-
- Console.WriteLine(a * b);
- }
- }
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).