Dot Net For All

Achieving Loose Coupling using Dependency Injection in C#

In this article I will discuss about the tight coupling and loose coupling. Why loose coupling is a better way of programming? How to achieve loose coupling using dependency injection? How to achieve dependency injection using unity framework ? You should be able to answer all these questions after reading the article. All there topics I will discuss here with the help of C# code examples.

Before starting the article you can learn about interface here and here in my articles.

What is Loose Coupling

To understand loose coupling we should first know what is tight coupling. Tight coupling is the way of initializing the class instances which make one class to totally depend on the instance of other class.

This means that to change the working of one class we have to change the internals of other class.

Please have a look at the below code example.

    public class EmployeesData
    {
        MSSqlData _msSqldata;
        public EmployeesData()
        {
            _msSqldata = new MSSqlData();
        }

        public void GetAll()
        {
            _msSqldata.GetAll();
        }

        public void GetEmployeeByID(int Id)
        {
            _msSqldata.GetByID(Id);
        }
    }

    internal class MSSqlData
    {
        internal void GetAll()
        {
            //Contains Logic to get all the data
        }

        internal void GetByID(int id)
        {
            //Contains logic to return data by ID
        }
    }

In the above code snippet I have created a class which retrieves the employee data. It creates the instance of the MSSqlData class and used it to get the data.

Here we can see the direct interaction between the two classes. Two classes are tightly associated. You can read about association, aggregation and composition here in this articleif I want to change the data recovery part to some other mode, like XML,some webservice or using some other data base by creating new classes.

In that case I have to change the implementation of the EmployeeData class.

Inversion Of Control(IoC) and Dependency Injection(DI)

To remove the dependency for retrieving the data, I have to hand over the control to more abstract layer.

Here I can say that I can handover the control to an interface. I will create a variable of interface Type and use in the EmployeeData class.

To achieve the loose coupling I have abstracted the operations of the data extraction in an interface.

Whatever way we want to extract the data, we can implement the interface and provide the instance variable to the EmployeeData class as shown in the figure below.

Dependency Injection

I can create an IDataProvider to use the above EmployeeData class. Please check the code below.

            IDataProvider mssqlData = new MSSqlData();
            EmployeesData empData = new EmployeesData(mssqlData);

If we want to use the Oracle database and change the implementation. There is no need to change the EmployeeData class internals.

Using Unity Container to have Dependency Injection

In the above code we are creating an instance of the MSSqlData class and assigning it to a variable of type IDataProvider. EmployeeData class is using that variable for its constructor. All this is process of creating and injecting the reference is static in the above code.

Containers are used to make this process of Dependency injection dynamic. Here I will discuss Unity Container to inject dependency at run time.

Install the Unity container by Typing “Install-Package Unity” in console manager. Please check the figure below.

Unity Container

To use the unity container more effectively I will abstract out the EmployeeData class. I have created the an Interface IEmployeeData as shown below.

    public interface IEmployeeData
    {
        void GetAll();
        void GetEmployeeByID(int id);
    }

and implement this interface to the EmployeeData class.

I have to create the dependency resolver using the unity container. The code for same is shown below.

            IUnityContainer container = new UnityContainer();
            container.RegisterType<IDataProvider, MSSqlData>().RegisterType<IEmployeeData,
                                                                              EmployeesData>();
            IEmployeeData employeeData = container.Resolve<IEmployeeData>();
            employeeData.GetAll();

This code will be generally placed along with the initialization code of the application. In this code I am specifying the IDataProvider interface to be resolved to the MSSqlData class instance and IIEmployeeData interface to be resolved to the EmplpyeeData class.

In the third line I have asked for IEmplyeeData instance. Unity container resolved it to EmplyeeData class. But before returning the instance it sees that the constructor of the EmployeeData class needs an instance of the IDataProvider. Unity Container checks in its repository and sees that to resolve the IDataProvder it has class of type MSSqlData. And in turn returns the instance of MSSqlData to the EmplyeeData constrcutor.

Here we can see that all the process of creating instance and providing dependency injection is automated. This can be very useful for writing the test and code which is easily extensible.

Conculsion:

In this article I have talked about purpose of dependency injection. How we can use it to write more robust and clean code.Further I have discussed Unity Container which can be used to resolve the dependencies at run time.

Top career enhancing courses you can't miss

My Learning Resource

Excel your system design interview