Dependency Injection in C#

In this blog, we will understand Dependency Injection? And, how we can implement Dependency Injection in C#?

What is Dependency Injection (DI)?

Dependency Injection is a design approach, which helps to create loosely coupled code. In another way, we can say that Dependency Injection is used to remove dependency between two classes and helps to create independent classes.

If an object has been passed from the container, then its dependencies will be automatically supplied by that container. This style allows you to consume a dependency and no need to create an object manually. This avoids tight coupling and gives you better control over the code structure.

Before implementing DI, we will see the problem that could occur in regular coding style.
Look at below code snippet.

class Program
    {
        static void Main(string[] args)
        {
            PayrollSystem objPaySystem = new PayrollSystem();
            objPaySystem.ProcessSalary();
        }
    }

    class PayrollSystem
    {
        PermanantEmployee objEmp = new PermanantEmployee();
        public void ProcessSalary()
        {
            objEmp.ProcessSalary(this);
        }

    }

    class PermanantEmployee
    {
        public void ProcessSalary(PayrollSystem paySystem)
        {
            Console.WriteLine("Salary Processed");
            Console.ReadLine();
        }
    }



Let's make code more complex Add more Employee Type to the Payroll system i.e. Contract Type Employee

To do this, create an Interface and name it IEmployee which will contain a method ProcessSalary

interface IEmployee
    {
        void ProcessSalary(PayrollSystem paySystem);
    }


Add one more class for Contract Employee and implement with the Interface created above.

Create a parameterized constructor for PayrollSystem class which accepts a type of employee of integer type and create an object based on employee type.

Go through with below sample code.

    class Program
    {
        static void Main(string[] args)
        {
            PayrollSystem objPaySystem = new PayrollSystem(1);
            objPaySystem.ProcessSalary();
        }
    }

    class PayrollSystem
    {
        //PermanantEmployee objEmp = new PermanantEmployee();
        IEmployee emp;
        public PayrollSystem(int employeeType)
        {
            if (employeeType == 1)//1 means Permanant Employee
            {
                emp = new PermanantEmployee();

            }

                //For Contract Employee
            else
            {
                emp = new ContractualEmployee();
            }
        }

        public void ProcessSalary()
        {
            emp.ProcessSalary(this);
        }

    }

    class PermanantEmployee : IEmployee
    {
        public void ProcessSalary(PayrollSystem paySystem)
        {
            Console.WriteLine("Salary Processed for Permanant Employee");
            Console.ReadLine();
        }
    }

    class ContractualEmployee : IEmployee
    {
        public void ProcessSalary(PayrollSystem paySystem)
        {
            Console.WriteLine("Salary Processed for Contract Employee");
            Console.ReadLine();
        }
    }


In the above Coding style, there is one issue. PayrollSystem class should handle the logic related to the Payment system and processing the salary. But we have added more liabilities to this class. This class also determines the type of Employee for which salary will be processed, in this case, PayrollSystem is tightly coupled with changes in Employee class and this is not a good coding practice.

So the decision making section i.e. checking type of employee will be moved or inverted to an external entity. This coding style is known as Inversion of Control (IoC).

What is Inversion of Control?

Inversion of Control (IoC) is a generic coding style of a software application that helps in creating reusable, loosely coupled classes that are easy to maintain.

Inversion of Control (IoC) states that changes in lower modules should not affect the higher level of a module. IoC enables loose coupling for better software design and easy testing of software components.

Relation between Inversion of Control and Dependency Injection

Inversion of Control (IOC) and Dependency Injection (DI) are used interchangeably. DI is the way to achieve IoC. Also, DI is not the only way to achieve IOC.

How to implement Dependency Injection in C# Code?

Let's demonstrate DI by using a sample code.

First, create an interface IEmployee (We have already created above)

interface IEmployee
    {
        void ProcessSalary(PayrollSystem paySystem);
    }




In below code, a parameterized constructor is created, parameter type is of IEmployee and based on the object only a particular function from a class will be called.

So, the dependency of checking Employee Type has been removed from PayrollSystem.

So, whatever object you will pass to the PayrollSystem, that respective class will be called.

class Program
    {
        static void Main(string[] args)
        {
            PayrollSystem objPaySystem = new PayrollSystem(new ContractualEmployee());
            objPaySystem.ProcessSalary();
        }
    }

    class PayrollSystem
    {
        //PermanantEmployee objEmp = new PermanantEmployee();
        IEmployee emp;
        public PayrollSystem(IEmployee empType)
        {
            emp = empType;
        }

        public void ProcessSalary()
        {
            emp.ProcessSalary(this);
        }

    }

    class PermanantEmployee : IEmployee
    {
        public void ProcessSalary(PayrollSystem paySystem)
        {
            Console.WriteLine("Salary Processed for Permanant Employee");
            Console.ReadLine();
        }
    }

    class ContractualEmployee : IEmployee
    {
        public void ProcessSalary(PayrollSystem paySystem)
        {
            Console.WriteLine("Salary Processed for Contract Employee");
            Console.ReadLine();
        }
    }


Why use Dependency Injection?

By looking at above definition of Dependency Injection, it is absolutely clear that Dependency Injection is used to create independent classes. DI enables to make our code maintainable, it also reduces future complexities and dependencies in classes.

Types of Dependency Injection

Below types of DI is available -
  • Constructor Injection
  • Property Injection
  • Method Injection
In this blog, I have used Constructor Injection to implement Dependency Injection pattern.


Comments

Popular