Need of Dependency Injection
Traditional Approach of Creating Application:
We create application with multiple classes and we required to create new object of another class to perform specific operation in class. For example we have application in three layer architecture UI Layer, Business Layer & Data Access Layer and we required to create Data Access Layer class object in business layer class for accessing data with the “New” keyword by this way we create an application and application running smoothly without any issue
Issue with above Approach:
- It is difficult to maintain over time (tightly Coupled)Over the time if Data Access class change its constructor at that time it break the Business Layer classes which are dependent on that class & it is hard to manage in every changes.
- Hard to Unit TestIt is hard to mock Data Access layer classes in unit test case of Business layer classes & make it complex.
Dependency injection Solve this problem, because it remove dependency between object and make object independent
What is Dependency Injection?
Dependency Injection is technique (Design Pattern) which helps to inject dependent object of a class. And make class independent
In above example we can see that in tightly coupled class are there. And if any changes happen in Item class Constructor then we need to change in Order class as well. And in dependency injection you no need to worry about any changes happen in Item Constructor it responsibility of Dependency Injection Container which create object of item class at time of order object create and so on it also take care if Item class also dependent on another class.There are three types of dependencies:
- Setter (Property)
Note: In this blog I am showing Constructor Injection with Unity Framework (that is mostly widely used).
Dependency Injection Container
A Dependency Injection Container is an object that knows how to instantiate and configure objects. And to be able to do its job, it needs to know about the constructor arguments and the relationships between the objects. It is responsible for create new object and return whenever it required or requested.
Implementation of Dependency Injection with example
I am going to create one console application by following steps
1. Create Console Application in visual studio by creating New Project with name “DIProject”
2. Adding the Reference of Microsoft Unity Framework using Nuget Package Manager
3. Now I am adding Order Class which is responsible for putting Order of Item
4. Create IProducts Interface which is implemented by item classes
5. Same as add 2 Item Class Tea and Coffee both Implemented IProducts interface
6. Now In Order Constructor we inject IProduct interface and create putTeaOrder method
7. Now we need to configure Unity Container so we can it provide object at time of resolve Interface.
8. Now resolve dependency from container by using Resolve method of container as mention below for Order
9. Now Calling PutTeaOrder Method of Order class
10. Snapshot of entire configuration & calling method
11. Now put debugger in Order class constructor & debug the program. you can find that the tea class object is resolve by Unity Container and assign to _products object variable
12. When you run the program then you see the result like this
Now you have clear idea about Dependency Injection & how it configurable, And Order Class behave as independent class if any one change constructor of Tea class then also no need to change Order Class as all thing manage by Unity Container
Register Single type with multiple Classes & Runtime Resolve Object
Continue with above example, have you notice that I implement IProducts Interface in two classes Tea and Coffee but I use only one Tea. Now we change requirement that we need to add one more product Coffee required to add in order. For this we already created class Coffee.
1. Register Type single type with two classes as mention below, it also call Name Binding
2. Now make some changes in Order Class as mention below
as you see that I declare IUnityContainer Interface to inject UnityContainer which help to Resolve register type IProducts at runtime. Also I added string parameter item in method which pass from program.cs for identify which item going to place order.
3. Also modify in Main method for calling PutTeaOrder with parameter as describe below
4. Now Debug the Program with putting debugger at PutTeaOrder method in order class
5. As display above screen we can see that if we pass item as Tea then it will resolve Tea object same if we pass Coffee then it resolve Coffee object
Dependency Injection Pros and Cons
- Loosely Coupling
- Increase Testability
- Increase code complexity
- Complicate debugging of code.