Back to: Design Patterns in C# With Real-Time Examples
Dependency Injection Design Pattern in C# with Examples
In this article, I am going to discuss the Dependency Injection Design Pattern in C# with Examples. Please read our previous article where we discussed the Singleton Design Pattern in C# with Examples. Nowadays, the dependency injection design pattern is one of the most frequently used design patterns in real-time applications. So, as a developer, you should know why and how to use the Dependency Injection Design Pattern in C#. We divided the dependency injection design pattern into three parts. As part of this article, we are going to discuss the following pointers in detail.
- Why Do We Need Dependency Injection (DI) Design Pattern in C#?
- What are Tight Coupling and Loose Coupling in Software Design?
- What is Dependency Injection Design Pattern in C#?
- Types of Dependency Injection Design Pattern in C#.
Constructor Injection
Property Injection
Method Injection - Example using Constructor Dependency Injection
- What are the Advantages of Constructor Dependency Injection?
In part 2, we are going to discuss Property and Method Dependency Injection with examples. And in part 3, we are going to discuss the Dependency Injection Design Pattern using Unity Container in C# with an example.
Why do we need the Dependency Injection Design Pattern in C#?
The Dependency Injection Design Pattern in C# allows us to develop loosely coupled software components. In other words, we can say that Dependency Injection Design Pattern is used to reduce the tight coupling between the software components. As a result, we can easily manage future changes and other complexity in our application.
Before understanding the Dependency Injection Design Pattern using C#, let us first understand what is tight coupling and what is loose coupling in software development. So let’s understand these two concepts first.
What is Tight Coupling in Software Design?
Tight coupling means two objects are dependent on each other. That means when a class is dependent on another class, then it is said to be a tight coupling between these two classes. In that case, if we change the dependent object, then we also need to change the classes where this dependent object is used. If your application is a small one, then it is not that difficult to handle but if you have a big enterprise-level application, then it’s really very difficult to handle to make these changes.
What is Loose Coupling in Software Design?
Loosely coupling means two objects are independent of each other. That means if we change one object then it will not affect another object. The loosely coupled nature of software development allows us to manage future changes easily and also allows us to manage the complexity of the application.
What is Dependency Injection Design Pattern in C#?
The Dependency Injection Design Pattern in C# is a process in which we are injecting the object of a class into a class that depends on that object. The Dependency Injection design pattern is the most commonly used design pattern nowadays to remove the dependencies between the objects.
Dependency Injection (DI) is a design pattern used to implement IoC (Inversion of Control). It allows the creation of dependency objects outside of a class and provides those objects to a class in different ways. Using Dependency Injection Design Pattern, we move the creation and binding of the dependent objects outside of the class that depends on them.
Dependency Injection pattern involves 3 types of classes:
- Client Class: The Client class (dependent class) is a class that depends on the service class.
- Service Class: The Service class (dependency) is a class that provides service to the client class.
- Injector Class: The Injector class injects the service class object into the client class.
For better understanding, please have a look at the following diagram.
As you can see above in the above diagram, the injector class creates an object of the service class and injects that object into a client class. In this way, the Dependency Injection Design Pattern separates the responsibility of creating an object of the service class out of the client class.
Different Types of Dependency Injection in C#?
The injector class injects the dependency object into a class in three different ways. They are as follows.
- Constructor Injection: When the Injector injects the dependency object (i.e. service) through the client class constructor, then it is called Constructor Dependecy Injection.
- Property Injection: When the Injector injects the dependency object (i.e. service) through the public property of the client class, then it is called Property Dependency Injection. This is also called the Setter Injection.
- Method Injection: When the Injector injects the dependency object (i.e. service) through a public method of the client class, then it is called Method Dependency Injection. In this case, the client class implements an interface that declares the method(s) to supply the dependency object and the injector uses this interface to supply the dependency object (i.e. service) to the client class.
Here, in this article, we will discuss how to inject the dependency object through the constructor. In the next article, I am going to discuss the Method and Property Dependency injection in C# with examples.
Constructor Dependency Injection in C#:
Let us understand the Constructor Dependency Injection in C# with an example. Let’s create a console application. to do so select, File => New => Project which will open the below New Project window, From this window, select the console application and provide a meaningful name and click on the OK button as shown in the below image.
Once you create the Console Application, next we will create 3 classes Employee.cs, EmployeeDAL.cs and EmployeeBL.cs as shown below
Employee.cs
Create a class file with the name Employee.cs and then copy and paste the following code into it. Here we created the Employee class with three properties.
namespace DependencyInjectionExample { public class Employee { public int ID { get; set; } public string Name { get; set; } public string Department { get; set; } } }
EmployeeDAL.cs
Create a class file with the name EmployeeDAL.cs and then copy and paste the following code into it. Here we created the EmployeeDAL class with one method i.e. SelectAllEmployees which returns the list of Employees.
namespace DependencyInjectionExample { public class EmployeeDAL { public List<Employee> SelectAllEmployees() { List<Employee> ListEmployees = new List<Employee>(); //Get the Employees from the Database //for now we are hard coded the employees ListEmployees.Add(new Employee() { ID = 1, Name = "Pranaya", Department = "IT" }); ListEmployees.Add(new Employee() { ID = 2, Name = "Kumar", Department = "HR" }); ListEmployees.Add(new Employee() { ID = 3, Name = "Rout", Department = "Payroll" }); return ListEmployees; } } }
EmployeeBL.cs
Create a class file with the name EmployeeBL.cs and then copy and paste the following code into it. Here we created the EmployeeBL class with one method i.e. GetAllEmployees which returns the list of Employees.
namespace DependencyInjectionExample { public class EmployeeBL { public EmployeeDAL employeeDAL; public List<Employee> GetAllEmployees() { employeeDAL = new EmployeeDAL(); return employeeDAL.SelectAllEmployees(); } } }
In the above code, in order to get the data, the EmployeeBL class depends on the EmployeeDAL class. In the GetAllEmployees() method of the EmployeeBL class, we create an instance of the EmployeeDAL (Employee Data Access Layer) class and then invoke the SelectAllEmployees() method. This is tight coupling because the EmployeeDAL is tightly coupled with the EmployeeBL class. Every time the EmployeeDAL class changes, the EmployeeBL class also needs to change. Let us see how to use the constructor injection to make these classes loosely coupled.
Using Constructor Dependency Injection Design Pattern in C#
Let us see how we can use the Constructor Dependency Injection Design Pattern in C# to make these classes loosely coupled. So, first Modify the EmployeeDAL.cs file as shown below. As you can see in the below code, first we create one interface i.e IEmployeeDAL with the one abstract method i.e. SelectAllEmployees. Then that interface is implemented by the EmployeeDAL class and provide implemenation for the abstract SelectAllEmployees.
namespace DependencyInjectionExample { public interface IEmployeeDAL { List<Employee> SelectAllEmployees(); } public class EmployeeDAL : IEmployeeDAL { public List<Employee> SelectAllEmployees() { List<Employee> ListEmployees = new List<Employee>(); //Get the Employees from the Database //for now we are hard coded the employees ListEmployees.Add(new Employee() { ID = 1, Name = "Pranaya", Department = "IT" }); ListEmployees.Add(new Employee() { ID = 2, Name = "Kumar", Department = "HR" }); ListEmployees.Add(new Employee() { ID = 3, Name = "Rout", Department = "Payroll" }); return ListEmployees; } } }
The point that you need to keep in mind is when you are going to use the Dependency Injection Design Pattern in c#, then the dependency object should be interface-based. In our example, the EmployeeDAL is the dependency object as this object is going to be used by the EmplyeeBL class. So we created the interface and then implement that interface.
Modify the EmployeeBL.cs
Next modify the EmployeeBL.cs file as shown below. As you can see in the below code, here we created one constructor which accepts one parameter of the dependency object type. The point that you need to keep focus is, the parameter of the constructor is of the type interface, not the concrete class. Now, this parameter can accept any concrete class object that implements the IEmployeeDAL interface.
namespace DependencyInjectionExample { public class EmployeeBL { public IEmployeeDAL employeeDAL; public EmployeeBL(IEmployeeDAL employeeDAL) { this.employeeDAL = employeeDAL; } public List<Employee> GetAllEmployees() { Return employeeDAL.SelectAllEmployees(); } } }
So here in the EmployeeBL class, we are not creating the object of the EmployeeDAL class. Instead, we are passing it as a parameter to the constructor of the EmployeeBL class. As we are injecting the dependency object through the constructor, it is called constructor dependency injection in C#.
Client Code:
Let’s see how to use EmployeeBL class in our Main method of Program class which is going to be our client. As you can see in the below code, first we create the object of EmployeeBL class and while creating the object we are passing EmployeeDAL instance to the constructor of the EmployeeBL class. Then we are calling the GetAllEmployees method which returns the list of employees.
namespace DependencyInjectionExample { class Program { static void Main(string[] args) { EmployeeBL employeeBL = new EmployeeBL(new EmployeeDAL()); List<Employee> ListEmployee = employeeBL.GetAllEmployees(); foreach(Employee emp in ListEmployee) { Console.WriteLine("ID = {0}, Name = {1}, Department = {2}", emp.ID, emp.Name, emp.Department); } Console.ReadKey(); } } }
Now run the application and you will see the output as expected as shown below.
Advantages of Constructor Dependency Injection
- The Constructor Dependency Injection Design Pattern makes a strong dependency contract
- This design pattern support testing as the dependencies are passed through the constructor.
In the next article, I am going to discuss the Property and Method dependency injection with real-time examples. Here, in this article, I try to explain the Dependency Injection Design Pattern in C# with an example. I hope you understood the need and use of the Dependency Injection Design Pattern in C#.
Thank you
Can´t believe it! I’ve got it!
Thanks a lot…
Thanks
one of the most finest explanation ever.
Solid, la-jawab, no words. there is a need to explained this wonderful knowledge, information buddy.
Simple and best…
But still we need to change in EmployeeDAL class and EmployeeBL if we change the interface. Suppose if we add new method or rename the existing method in Interface then still we are facing tight coupling issue
But still we need to change in EmployeeDAL class and EmployeeBL if we change the interface. Suppose if we add new method or rename the existing method in Interface then still we are facing tight coupling issue
Hi Sandeep,
Not really. It depends.
Please refer to the SRP, Repo pattern and interface sagregaton principle for better understanding
Excellent Explanation !!
Dependency Injection it’s implementation an interface and using it. Right?
I’m just starting my trip. Don`t get mad 🙂
Thanq for valuable information
simple and best
nice lesson
in client(main method) again we are creating the DAL object using the new keyword, tomorrow if the class is removed client has to change the code. little confused, please explain.
main method
EmployeeBL employeeBL = new EmployeeBL(new EmployeeDAL());
You are correct with your observation. 🙂 Yes, at some point in the object hierarchy, you will have to create the objects. This is unavoidable.
In real world applications, this problem is solved using so called “Inversion of Control-Containers” (IoC-Containers).
To keep it simple: a container is a class on which you register your interfaces and implementations. The container then creates all necessary objects in the object hierarchy when you are using a class.
Example of how such a container could be used in code:
Container container = new Container();
container.Register();
container.Register();
EmployeeBL resolvedObject = container.Resolve();
The Resolve() method makes the container create all objects that are necessary to create EmployeeBL. If those objects have dependencies as well, then those will be created too, and so on.
Because developers usually don’t want to write hundreds of lines of container.Register() calls for all types in their project, the registration is usually automated using reflection, so once it is set up you will never have to register anything manually during the lifetime of your project.
The important part in all this is that EmployeeBL will never have to know about the implementation of IEmployeeDAL. The only one who really cares is the entry point of your application or the IoC-Container. So even if you change EmployeeDAL or replace it with another class that implements IEmployeeDAL, EmployeeBL will never break.
thanks
Nice! Explanation, Thanks thanks a lot.
Doing a great job sir
Lots of thanks from bottom of my heart
Really Great. I was very difficult to understand but after read your post now comfortable.
Thanx
Thanks
Thanks that was very helpful.
Thank you