Inversion of Control and Dependency Injection

Introduction

This article explains Inversion of Control and Dependency Injection. Inversion of control is a principle and dependency injection is a way of implementing inversion of control. This article also explains each method with an example.

What is Inversion of Control?

public class clsDAL
{
    private clsSqlServer _sql; 
 
    public clsDAL()
    {
        _sql = new clsSqlServer(); 
    }
}

Consider the above example, where we have a DAL class. The default constructor of the DAL class creates an object of the SqlServer class. That means the DAL Class is responsible for creating an object of the SqlServer class. So there is tight coupling between the DAL class and SqlServer class.

Three main problems in the above code:

  1. The DAL class is responsible for creating an object of the SqlServer class.
  2. The SqlServer class is directly referenced in the DAL class.
  3. The DAL class should be aware of the SqlServer class type.

Now we understand the problem. Now let's discuss the solution. The solution is to shift the object creation part from this class. We need to shift the object creation control from here i.e. Inversion of control.

Principles of IOC

  1. Main classes aggregating other classes should not depend on the direct implementation of the aggregated classes. Both the classes should depend on abstraction.
  2. Abstraction should not depend on details, details should depend on abstraction.

What is Dependency Injection?

Inversion of control is implemented by dependency injection because Inversion of control is a principle and dependency injection is a way of implementing IOC.

Ways of implementing IOC

Implementing-IOC.jpg

Now let's discuss each method with an example.

Constructor Methodology

public class clsDAL
{
    private ISql _sql;    public clsDAL(ISql obj)
    {
         _sql = obj;
    }
}    

In this methodology we pass an object of SQL into the DAL class. Here in the above code you can see that there is a parameterized constructor in the DAL class. And the parameterized constructor accepts an object of SQL. The DAL class is not responsible for creating an object of SQL in this case. So there is no tight coupling between these classes. This method is not useful for the client who only can use a default constructor.

Setter and Getter

public class clsDAL
{
    private ISql _sql;    public Isql Sql
    {
        set
        { 
             _sql = value; 
        }
    }
}

In this method we expose an object of SQL through the get/set methods of the DAL class. But it violates the encapsulation rule of OOP. Encapsulation means hiding internal details of an object. So here rather than hiding an object, we are exposing an object.

Interface Implementation

interface ISqlDI
{
    void setConnection(ISql obj);
}
public class clsDAL : ISqlDI
{
    private ISql _sql;    public void setConnection(ISql obj)
    {
        _sql = obj;
    }
}

In the preceding code we have implemented an interface which has a setConnection method which sets the SQL object. And the DAL class implements a SQL interface. So with the help of the setConnection method the client can inject a SQL object in the DAL class.

Server Locator

static class LocateConnection
{
    public static ISql getConnection() { }
}

 interface clsDAL
{
    private ISql _sql;
 
    public clsDAL()
    {
        _sql = LocateConnection.getConnection();
    }
}

In this method we create a static class and a static method inside this class. The DAL class calls this static method from its default constructor. So in this way the SQL object is injected into the DAL class.