Dependency Injection Design Pattern in C#

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

  1. Why Do We Need the Dependency Injection (DI) Design Pattern in C#?
  2. What is Tight Coupling and Loose Coupling in Software Design?
  3. What is Dependency Injection Design Pattern in C#?
  4. Types of Dependency Injection Design Pattern in C#.
          Constructor Injection
          Property Injection
          Method Injection
  5. Example using Constructor Dependency Injection
  6. 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 complexities in our application. In this case, if we change one component, then it will not impact the other components.

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.

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 being used. If your application is a small one, then it is not that difficult to handle the changes but if you have a big Enterprise-Level application, then it’s really very difficult to handle 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 dependent 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 that depends on it in three different ways (i.e. using Constructor, Method, and Property). The Dependency Injection Design Pattern involves 3 types of classes:

  1. Client Class: The Client Class (dependent class) is a class that depends on the Service Class. That means the Client Class wants to use the Services (Methods) of the Service Class.
  2. Service Class: The Service Class (dependency) is a class that provides the actual services to the client class.
  3. Injector Class: The Injector Class is a class that injects the Service Class object into the Client Class.

For a better understanding, please have a look at the following diagram.

Dependency Injection Design Pattern in C#

As you can see above in the above diagram, the Injector Class creates an object of the Service Class and injects that object into the Client Class. And then the Client Class uses the Injected Object of the Service Class to call the Methods of the Service Class. So, 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 the Client Class in three different ways. They are as follows.

  1. Constructor Injection: When the Injector Injects the Dependency Object (i.e. Service Object) into the Client Class through the Client Class Constructor, then it is called Constructor Dependency Injection.
  2. Property Injection: When the Injector Injects the Dependency Object (i.e. Service Object) into the Client Class through the public Property of the Client Class, then it is called Property Dependency Injection. This is also called the Setter Injection.
  3. Method Injection: When the Injector Injects the Dependency Object (i.e. Service Object) into the Client Class through a public Method of the Client Class, then it is called Method Dependency Injection. 

Here, in this article, we will discuss How to Inject the Dependency Object through the Client Class Constructor i.e. Constructor Dependency Injection. And, in the next article, I am going to discuss How to Implement Method and Property Dependency Injection in C# with Examples.

Example to Understand Dependency Injection Design Pattern in C#:

Let us understand the Dependency Injection Design Pattern in C# with an Example. Let us first create a Console Application with the name DependencyInjectionExample. Once you create the Console Application, next we are going to create 3 classes Employee, EmployeeDAL, and EmployeeBL.

The Employee is the Model class that is going to hold the Employee data and this Model class is going to be used by both EmployeeDAL and EmployeeBL classes. The EmployeeDAL is the class that is going to interact with the database and also provides the methods to perform the database operations. EmployeeBL is the class where we are going to implement the business logic and validation logic and then the EmployeeBL class will use the EmployeeDAL class methods to save the data in the database. That means here, EmployeeBL class depends on the EmployeeDAL class. So, here, EmployeeDAL is the dependency Object and EmployeeBL is the dependent object.

Example without using Dependency Injection Design Pattern in C#:

First, we will implement the Example without using Dependency Injection Design Pattern and we will see the problem and then we will see how we can overcome the problems using Dependency Injection Design Pattern in C#.

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. This is going to be our Model class which holds the Model data. This class is going to be used by both EmployeeDAL and EmployeeBL.

namespace DependencyInjectionDesignPattern
{
    //This is going to be our Model class which holds the Model data
    //This class is going to be used by both EmployeeDAL and EmployeeBL
    public class Employee
    {
        public int ID { get; set; }
        public string Name { get; set; }
        public string Department { get; set; }
    }
}
EmployeeDAL.cs (Service)

This is going to be the Service class which is providing services to be used by the Client. So, create a class file with the name EmployeeDAL.cs and then copy and paste the following code into it. This is the class that is responsible for Interacting with the Database. This class is going to be used by the EmpoloyeeBL class. That means it is going to be the Dependency Object. Here we created the EmployeeDAL class with one method i.e. SelectAllEmployees which returns the list of Employees. Even if required, you can have multiple methods like SaveEmployee, DeleteEmployee, etc. as per your business requirement. 

using System.Collections.Generic;
namespace DependencyInjectionDesignPattern
{
    //Service Class or Dependency Object
    //This is the class that is responsible for Interacting with the Database
    //This class is going to be used by the EmpoloyeeBL class
    //That means it is going to be the Dependency Object
    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
                new Employee() { ID = 1, Name = "Pranaya", Department = "IT" },
                new Employee() { ID = 2, Name = "Kumar", Department = "HR" },
                new Employee() { ID = 3, Name = "Rout", Department = "Payroll" }
            };
            return ListEmployees;
        }
    }
}
EmployeeBL.cs (Client)

This is going to be the client class which is going to consume the services provided by the Service class. So, create a class file with the name EmployeeBL.cs and then copy and paste the following code into it. This is the Class that is going to consume the services provided by the EmployeeDAL Service Class. That means it is the Dependent Class which is Depending on the EmployeeDAL Service Class. Here we created the EmployeeBL class with one method i.e. GetAllEmployees which returns the list of Employees. 

using System.Collections.Generic;
namespace DependencyInjectionDesignPattern
{
    //Client Class or Dependent Object
    //This is the Class that is going to consume the services provided by the EmployeeDAL Class
    //That means it is the Dependent Class which is Depending on the EmployeeDAL Class
    public class EmployeeBL
    {
        public EmployeeDAL employeeDAL;
        public List<Employee> GetAllEmployees()
        {
            //Creating an Instance of Dependency Class means it is a Tight Coupling
            employeeDAL = new EmployeeDAL();
            return employeeDAL.SelectAllEmployees();
        }
    }
}

As you can see 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 a 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. This is the problem. Let us see how to use the Constructor Dependency 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 class file as shown below. As you can see in the below code, first we create one interface i.e IEmployeeDAL with one abstract method i.e. SelectAllEmployees. Then that interface is implemented by the EmployeeDAL class and provides implementations for the abstract SelectAllEmployees method.

using System.Collections.Generic;
namespace DependencyInjectionDesignPattern
{
    //Service Class or Dependency Object
    //Dependency Object should be Interface-Based
    public interface IEmployeeDAL
    {
        List<Employee> SelectAllEmployees();
    }
    
    //This is the class that is responsible for Interacting with the Database
    //This class is going to be used by the EmpoloyeeBL class
    //That means it is going to be the Dependency Object
    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
                new Employee() { ID = 1, Name = "Pranaya", Department = "IT" },
                new Employee() { ID = 2, Name = "Kumar", Department = "HR" },
                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 IEmployeeDAL interface and then implement that IEmployeeDAL interface in the EmployeeDAL class. 

Modify the EmployeeBL.cs

Next, we need to modify the EmployeeBL.cs class 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 the focus on 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.

using System.Collections.Generic;
namespace DependencyInjectionDesignPattern
{
    //Client Class or Dependent Object
    //This is the Class that is going to consume the services provided by the IEmployeeDAL Class
    //That means it is the Dependent Class which Depending on the IEmployeeDAL Class
    public class EmployeeBL
    {
        public IEmployeeDAL employeeDAL;

        //Injecting the Dependency Object using Constructor means it is a Loose Coupling
        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#.

Injector Class:

The Injector class will Inject the Dependency Object (EmplpyeeDAL Object) into the Client Class (EmplpyeeBL Class). In our example, the Main method of the Program class is going to be the Injector Class. So, the Injector class will decide which EmployeeDAL instance to be used by the EmployeeBL class, and then the Injector will Inject that instance into the EmployeeBL class through the EmployeeBL class constructor as we are using Constructor Dependency Injection.

So, modify the Main method of the Program class as follows. As you can see in the below code, first we create the object of EmployeeBL class and while creating the object we are passing the EmployeeDAL instance as an argument to the constructor of the EmployeeBL class. Then we are calling the GetAllEmployees method which returns the list of employees. 

using System;
using System.Collections.Generic;
namespace DependencyInjectionDesignPattern
{
    class Program
    {
        static void Main(string[] args)
        {
            //Create an Instance of EmployeeBL and Inject the Dependency Object as an Argument to the Constructor
            EmployeeBL employeeBL = new EmployeeBL(new EmployeeDAL());
            List<Employee> ListEmployee = employeeBL.GetAllEmployees();
            foreach (Employee emp in ListEmployee)
            {
                Console.WriteLine($"ID = {emp.ID}, Name = {emp.Name}, Department = {emp.Department}");
            }
            Console.ReadKey();
        }
    }
}

Now run the application and you will see the output as expected as shown below.

Constructor Dependency Injection Design Pattern in C# with Examples

Advantages of Constructor Dependency Injection Design Pattern in C#
  1. The Constructor Dependency Injection Design Pattern makes a Strong Dependency Contract
  2. 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 in C# with Examples. Here, in this article, I try to explain the Dependency Injection Design Pattern in C# with Examples. I hope you understood the need and use of the Constructor Dependency Injection Design Pattern in C# with Examples.

37 thoughts on “Dependency Injection Design Pattern in C#”

    1. 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

      1. No. An interface is a contract. You cannot simply change the interface signature. You can add new services as per your requirement. The main objective of the Dependency Injection Design Pattern is that today you are using the EmployeeDAL class instance, tomorrow you might create a new EmployeeDAL class, let us say EmployeeDAL2 which is pointing to a different database or do some unit testing, then your EmployeeBL code is going to be unchanged. Simply, create the EmployeeDAL2 instance and pass that instance as an argument to the EmployeeBL class constructor while creating the instance of EmployeeBL class. Hope you understand.

  1. 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

    1. Hi Sandeep,

      Not really. It depends.

      Please refer to the SRP, Repo pattern and interface sagregaton principle for better understanding

  2. Dependency Injection it’s implementation an interface and using it. Right?
    I’m just starting my trip. Don`t get mad 🙂

  3. 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());

    1. 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.

  4. Olayinka Akinrimisi

    This Explanation has clarified Dependency Injection for me thanks. In practical terms if for example you are using Razor Pages you can merge the EmployeeBL code for the Injection with the Razor pages Client code. The EmployeeDAL Service would be a different class that gets data from say an MSSQL database. If for example you want to change your database type to another database e.g. MYSQL create another EmployeeDAL2 service code with the same Interface credentials.

    If your are using Visual studio, then use the builder.Services.AddTransient (IEmployeeDAL,EmployeeDAL2) method to change the service class in your program.cs . You do not have to change anything in your Razor Page Code.

Leave a Reply

Your email address will not be published. Required fields are marked *