Click here to Skip to main content
Click here to Skip to main content

Dependency Inversion Principle, IoC Container & Dependency Injection (Part - 2)

, 21 Apr 2013 CPOL
Rate this:
Please Sign up or sign in to vote.
This is the second part of article on Dependency Injection. It will give you an idea about what Inversion of Control is. There are other part of the article which explains about how to implement DIP.

Introduction

This is the continuation part of the article on Dependency Inversion Principle, IoC Container & Dependency Injection. In the previous part of this article I explained about what is Dependency Inversion Principle and its benefit. In this part of the article I will be covering Inversion Of Control (IoC) and what is an IoC Container.

The following are the listing of different parts of the article.

Background

Inversion of Control (IoC) 

What is Inversion of Control

Many people have different different opinion about Inversion of Control. You can have different meaning of it in different context of application. Basically it the pattern to invert the control of dependency by switching to another location who controls. 

DIP says a high-level module should not depend on low-level module and both high-level and low-level module should depend on an abstraction. If you want to prevent the changes in high-level module on changing of low-level module you need to invert the control so that low-level module will not control the interface and creation of objects that the high-level module needs. IoC is a pattern which provides that abstraction.

In the following example (derived from the previous part of the article), we are inverting the creation of dependency objects (reader and writer) by switching the code for creating dependency to service locator (marked in bold letters).

    public class Copy
    {
        public void DoWork()
        {
            IReader reader = serviceLocator.GetReader();
            IWriter writer = serviceLocator.GetWriter();
            string data = reader.Read();
            writer.Write(data);
        }
    }     

This is one of the example of Inversion Of Control. There can be various way to invert the control. But in the current software development trends there are 3 basic ways to invert the control. 

  • Interface Inversion   
  • Flow Inversion 
  • Creation Inversion

Interface Inversion 

This is a very common kind of inversion. I have discussed some about Interface Inversion in the first part of this article. By providing abstraction for all of our low-level modules doesn't mean that we have implemented DIP.

For example, we have two low-level modules Car and Bicycle and both are having their own abstraction. 

    public interface ICar
    {
        void Run();
    }
    public class Car : ICar
    {
        public void Run()
        {
            ....
        }
    }
 
    public interface IBicycle
    {
        void Move();
    }
    public class Bicycle : IBicycle
    {
        public void Move()
        {
            ....
        }
    }

In the above example although we have defined abstraction, but still there is a problem. The problem is each low-level module are having their own abstractions. So when high-level module interacts with the abstractions, high-level class has to treat each abstraction differently. For the above instance when high-level class holds instance of ICar it needs to invoke Run() method whereas when it holds instance of IBicycle then it needs to invoke Move(). So in the above case high-level class should have knowledge about the implementation of low-level module.

But Interface Inversion says the high-level module should define the abstraction, which should be followed by the low-level modules. The following example illustrates this.

    public interface IVehicle
    {
        void Move();
    }
    public class Car : IVehicle
    {
        public void Move()
        {
            ....
        }
    }
 
    public class Bicycle : IVehicle
    {
        public void Move()
        {
            ....
        }
    } 

In the above example both Car and Bicycle class implements IVehicle interface, which is defined by high-level class. In this case the high-level class should not bother about the instance of which, it contains the reference. It just invokes Move() method with the help of interface. 

Flow Inversion    

Flow Inversion talks about inverting the execution flow. For example, earlier in DOS based programs the program reads the value of each field sequentially. Until the value of first field is entered you can't enter the value of second field and subsequently for third and so on. The following is an example of console application written in C#. 

    static void Main(string[] args)
    {
        int nValue1, nValue2, nSum;

        Console.Write("Enter value1 :");
        nValue1 = Convert.ToInt32(Console.ReadLine());

        Console.Write("Enter value2 :");
        nValue2 = Convert.ToInt32(Console.ReadLine());

        nSum = nValue1 + nValue2;
        Console.WriteLine(string.Format("The sum of {0} and {1} is {2}", nValue1, nValue2, nSum));

        Console.ReadKey();
    }

Below is the output of the above program:

Here you can only enter the value of value2 only after giving value of value1. So entry of value2 is dependent on entry of value1.

But if you look at the following GUI application you can see how we can invert the flow to remove dependency.

Here the execution flows are inverted and now input of both value1 and value2 are independent of each other.

Creation Inversion 

In Creation Inversion the creation of dependency object are inverted from high-level module to some other place.

    public class Copy
    {
        public void DoWork()
        {
            IReader reader = serviceLocator.GetReader();
            IWriter writer = serviceLocator.GetWriter();
            string data = reader.Read();
            writer.Write(data);
        }
    }   

In the above program we have inverted the creation of IReader and IWriter objects to serviceLocator. Object creation responsibility is given to serviceLocator. And Copy program doesn't have any idea about the instance. So for any addition of new implementation class of IReader and IWriter, there is no need of modifying Copy program.

IoC container also other way to implement Creational Inversion. IoC container contains configuration settings for each abstraction and its implementation. Whenever there is a need of instance of an abstraction, IoC container provides that to the requester.  

In figure 1.a interface inversion is implemented but still there is a dependency, hence there is a tight-coupling between hight-level and low-level modules. But in figure 1.b this dependency is resolved with the implementation of IoC container.

The mechanism of injecting dependency to the high-level module (consumer) is called as Dependency Injection (DI). DI uses IoC container to resolve the dependency.

Dependency Injection

As I mentioned above DI is a mechanism of injecting dependency (low-level instance) to high-level module, and DI uses IoC container who holds the configuration settings related to dependency and resolves and abstraction upon request.

In .NET there are many IoC containers which provides facilities to inject dependencies upon request. Few of the most popular IoC containers are listed below:

  • Unity Container
  • Castle Windsor
  • NInject 
  • Structure Map

In the next part of the article I will explain how to implement our own custom IoC container, and the implementation of Dependecy Injection to resolve many issues related to layered based application.

Summary

In this part of the article I have tried to expain what is an Inversion of Control and how it resolves tight-coupling. Hope you found this topic good and easy to understand.

History

First revision : 14-March-2013 

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Chinmaya_Champatiray
Software Developer (Senior) PAREXEL International
India India
Life is short. So enjoy each and every moment of life.
And necessarily keep smiling. Smile | :)

Comments and Discussions

 
GeneralMy vote of 5 PinmemberGregoryW16-Apr-13 2:05 
GeneralRe: My vote of 5 PinmemberChinmaya_Champatiray16-Apr-13 5:14 
GeneralMy vote of 4 PinmemberSRIRAM 24-Apr-13 20:59 
GeneralMy vote of 4 PinmemberKotha Ramesh Babu20-Mar-13 22:24 
GeneralRe: My vote of 4 PinmemberChinmaya_Champatiray20-Mar-13 22:38 
GeneralMy vote of 3 PinmemberPaulo Zemek19-Mar-13 7:51 
GeneralRe: My vote of 3 PinmemberChinmaya_Champatiray19-Mar-13 8:19 
GeneralRe: My vote of 3 PinmemberPaulo Zemek19-Mar-13 8:30 
GeneralRe: My vote of 3 Pinmemberrrotstein11-Feb-14 8:51 
GeneralGood article PinmemberskaboFer14-Mar-13 2:47 
GeneralRe: Good article PinmemberChinmaya_Champatiray14-Mar-13 9:12 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web03 | 2.8.141022.2 | Last Updated 21 Apr 2013
Article Copyright 2013 by Chinmaya_Champatiray
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid