Inversion of Control vs Dependency Injection

Viewed 382433

According to the paper written by Martin Fowler, inversion of control is the principle where the control flow of a program is inverted: instead of the programmer controlling the flow of a program, the external sources (framework, services, other components) take control of it. It's like we plug something into something else. He mentioned an example about EJB 2.0:

For example the Session Bean interface defines ejbRemove, ejbPassivate (stored to secondary storage), and ejbActivate (restored from passive state). You don't get to control when these methods are called, just what they do. The container calls us, we don't call it.

This leads to the difference between framework and library:

Inversion of Control is a key part of what makes a framework different to a library. A library is essentially a set of functions that you can call, these days usually organized into classes. Each call does some work and returns control to the client.

I think, the point of view that DI is IOC, means the dependency of an object is inverted: instead of it controlling its own dependencies, life cycle... something else does it for you. But, as you told me about DI by hands, DI is not necessarily IOC. We can still have DI and no IOC.

However, in this paper (from the pococapsule, another IOC Framework for C/C++), it suggests that because of IOC and DI, the IOC containers and DI frameworks are far more superior to J2EE, since J2EE mixes the framework code into the components, thus not making it Plain Old Java/C++ Object (POJO/POCO).

Inversion of Control Containers other than the Dependency Injection pattern (Archive link)

Additional reading to understand what's the problem with old Component-Based Development Framework, which leads to the second paper above: Why and what of Inversion of Control (Archive link)

My Question: What exactly is IOC and DI? I am confused. Based on pococapsule, IOC is something more significant than just inversion of the control between objects or programmers and frameworks.

24 Answers

Rather than contrast DI and IoC directly, it may be helpful to start from the beginning: every non-trivial application depends on other pieces of code.

So I am writing a class, MyClass, and I need to call a method of YourService... somehow I need to acquire an instance of YourService. The simplest, most straightforward way is to instantiate it myself.

YourService service = new YourServiceImpl();

Direct instantiation is the traditional (procedural) way to acquire a dependency. But it has a number of drawbacks, including tight coupling of MyClass to YourServiceImpl, making my code difficult to change and difficult to test. MyClass doesn't care what the implementation of YourService looks like, so MyClass doesn't want to be responsible for instantiating it.

I'd prefer to invert that responsibility from MyClass to something outside MyClass. The simplest way to do that is just to move the instantiation call (new YourServiceImpl();) into some other class. I might name this other class a Locator, or a Factory, or any other name; but the point is that MyClass is no longer responsible for YourServiceImpl. I've inverted that dependency. Great.

Problem is, MyClass is still responsible for making the call to the Locator/Factory/Whatever. Since all I've done to invert the dependency is insert a middleman, now I'm coupled to the middleman (even if I'm not coupled to the concrete objects the middleman gives me).

I don't really care where my dependencies come from, so I'd prefer not to be responsible for making the call(s) to retrieve them. Inverting the dependency itself wasn't quite enough. I want to invert control of the whole process.

What I need is a totally separate piece of code that MyClass plugs into (call it a framework). Then the only responsibility I'm left with is to declare my dependency on YourService. The framework can take care of figuring out where and when and how to get an instance, and just give MyClass what it needs. And the best part is that MyClass doesn't need to know about the framework. The framework can be in control of this dependency wiring process. Now I've inverted control (on top of inverting dependencies).

There are different ways of connecting MyClass into a framework. Injection is one such mechanism whereby I simply declare a field or parameter that I expect a framework to provide, typically when it instantiates MyClass.

I think the hierarchy of relationships among all these concepts is slightly more complex than what other diagrams in this thread are showing; but the basic idea is that it is a hierarchical relationship. I think this syncs up with DIP in the wild.

Hierarchy of Dependency Acquisition

Inversion of Control is a generic design principle of software architecture that assists in creating reusable, modular software frameworks that are easy to maintain.

It is a design principle in which the Flow of Control is "received" from the generic-written library or reusable code.

To understand it better, lets see how we used to code in our earlier days of coding. In procedural/traditional languages, the business logic generally controls the flow of the application and "Calls" the generic or reusable code/functions. For example, in a simple Console application, my flow of control is controlled by my program's instructions, that may include the calls to some general reusable functions.

print ("Please enter your name:");
scan (&name);
print ("Please enter your DOB:");
scan (&dob);

//More print and scan statements
<Do Something Interesting>

//Call a Library function to find the age (common code)
print Age

In Contrast, with IoC, the Frameworks are the reusable code that "Calls" the business logic.

For example, in a windows based system, a framework will already be available to create UI elements like buttons, menus, windows and dialog boxes. When I write the business logic of my application, it would be framework's events that will call my business logic code (when an event is fired) and NOT the opposite.

Although, the framework's code is not aware of my business logic, it will still know how to call my code. This is achieved using events/delegates, callbacks etc. Here the Control of flow is "Inverted".

So, instead of depending the flow of control on statically bound objects, the flow depends upon the overall object graph and the relations between different objects.

Dependency Injection is a design pattern that implements IoC principle for resolving dependencies of objects.

In simpler words, when you are trying to write code, you will be creating and using different classes. One class (Class A) may use other classes (Class B and/or D). So, Class B and D are dependencies of class A.

A simple analogy will be a class Car. A car might depend on other classes like Engine, Tyres and more.

Dependency Injection suggests that instead of the Dependent classes (Class Car here) creating its dependencies (Class Engine and class Tyre), class should be injected with the concrete instance of the dependency.

Lets understand with a more practical example. Consider that you are writing your own TextEditor. Among other things, you can have a spellchecker that provides the user with a facility to check the typos in his text. A simple implementation of such a code can be:

Class TextEditor
{

    //Lot of rocket science to create the Editor goes here

    EnglishSpellChecker objSpellCheck;
    String text;

    public void TextEditor()

    {   

        objSpellCheck = new EnglishSpellChecker();

    }

    public ArrayList <typos> CheckSpellings()
    {

        //return Typos;

    }

}

At first sight, all looks rosy. The user will write some text. The developer will capture the text and call the CheckSpellings function and will find a list of Typos that he will show to the User.

Everything seems to work great until one fine day when one user starts writing French in the Editor.

To provide the support for more languages, we need to have more SpellCheckers. Probably French, German, Spanish etc.

Here, we have created a tightly-coupled code with "English"SpellChecker being tightly coupled with our TextEditor class, which means our TextEditor class is dependent on the EnglishSpellChecker or in other words EnglishSpellCheker is the dependency for TextEditor. We need to remove this dependency. Further, Our Text Editor needs a way to hold the concrete reference of any Spell Checker based on developer's discretion at run time.

So, as we saw in the introduction of DI, it suggests that the class should be injected with its dependencies. So, it should be the calling code's responsibility to inject all the dependencies to the called class/code. So we can restructure our code as

interface ISpellChecker
{

    Arraylist<typos> CheckSpelling(string Text);

}

Class EnglishSpellChecker : ISpellChecker

{

    public override Arraylist<typos> CheckSpelling(string Text)

    {

        //All Magic goes here.

    }

}



Class FrenchSpellChecker : ISpellChecker

{

    public override Arraylist<typos> CheckSpelling(string Text)

    {

        //All Magic goes here.

    }

}

In our example, the TextEditor class should receive the concrete instance of ISpellChecker type.

Now, the dependency can be injected in Constructor, a Public Property or a method.

Lets try to change our class using Constructor DI. The changed TextEditor class will look something like:

Class TextEditor

{

    ISpellChecker objSpellChecker;

    string Text;



    public void TextEditor(ISpellChecker objSC)

    {

        objSpellChecker = objSC;

    }



    public ArrayList <typos> CheckSpellings()

    {

        return objSpellChecker.CheckSpelling();

    }

}

So that the calling code, while creating the text editor can inject the appropriate SpellChecker Type to the instance of the TextEditor.

You can read the complete article here

IOC - DIP - DI

  1. Inversion of Control (IOC)
  2. Dependency Inversion Principle (DIP)
  3. Dependency Injection (DI)

1- IOC: abstract principle describing an aspect of some software architecture designs in which the flow of control of a system is inverted in comparison to procedural programming.

2-DIP: is Object Oriented Programming(OOP) principle(D of SOLID).

3-DI: is a software design pattern that implements inversion of control and allows a program design to follow the dependency inversion principle.

enter image description here IOC & DIP are two disjoint sets and DIP is the super set of DI, service locator and some other patterns

IOC (Inversion of Control) is basically design pattern concept of removing dependencies and decoupling them to making the flow non-linear , and let the container / or another entity manage the provisioning of dependencies. It actually follow Hollywood principal “Don’t call us we will call you”. So summarizing the differences.

Inversion of control :- It’s a generic term to decouple the dependencies and delegate their provisioning , and this can be implemented in several ways (events, delegates etc).

Dependency injection :- DI is a subtype of IOC and is implemented by constructor injection, setter injection or method injection.

The following article describe this very neatly.

https://www.codeproject.com/Articles/592372/Dependency-Injection-DI-vs-Inversion-of-Control-IO

I think the idea can be demonstrated clearly without getting into Object Oriented weeds, which seem to muddle the idea.

// dependency injection
function doSomething(dependency) {
    // do something with your dependency
}

// in contrast to creating your dependencies yourself
function doSomething() {
    dependency = getDependencySomehow()
}

// inversion of control
application = makeApp(authenticate, handleRequest, sendResponse)
application.run(getRequest())

// in contrast to direct control or a "library" style
application = makeApp()
request = application.getRequest()

if (application.authenticate(request.creds)) {
    response = application.handleRequest(request)
    application.sendResponse(response)
}

If you tilt your head and squint your eyes, you'll see that DI is a particular implementation of IoC with specific concerns. Instead of injecting models and behaviors into an application framework or higher-order operation, you are injecting variables into a function or object.

DIP vs DI vs IoC

[Dependency Inversion Principle(DIP)] is a part of SOLID[About] which ask you to use abstraction instead of realizations

Dependency Injection(DI) - use Aggregation instead of Composition[About] In this case external object is responsible for logic inside. Which allows you to have more dynamic and testable approach

class A {
  B b

  //injecting B via constructor 
  init(b: B) {
     self.b = b
  }
}

Inversion of Control(IoC) very high level definition which is more about control flow. The best example is Inversion of Control(IoC) Container or Framework[About]. For example GUI which is Framework where you don't have a control, everything which you can do is just implement Framework's interface which will be called when some action is happend in the Framework. So control is shifted from your application into the Framework being used

DIP + DI

class A {
  IB ib

  init(ib: IB) {
     self.ib = ib
  }
}

Also you can achieve it using:

More complex example

Dependency rule in multi layer/module structure

Pseudocode:

interface InterfaceInputPort {
    func input()
}

interface InterfaceOutputPort {
    func output()
}

class A: InterfaceOutputPort {

    let inputPort = B(outputPort: self)

    func output() {
        print("output")
    }
}

class B: InterfaceInputPort {
    let outputPort: InterfaceOutputPort

    init(outputPort: InterfaceOutputPort) {
        self.outputPort = outputPort
    }

    func input() {
        print("input")
    }
}

//ICO , DI ,10 years back , this was they way:

public class  AuditDAOImpl implements Audit{

    //dependency
    AuditDAO auditDAO = null;
        //Control of the AuditDAO is with AuditDAOImpl because its creating the object
    public AuditDAOImpl () {
        this.auditDAO = new AuditDAO ();
    }
}

Now with Spring 3,4 or latest its like below

public class  AuditDAOImpl implements Audit{

    //dependency

     //Now control is shifted to Spring. Container find the object and provide it. 
    @Autowired
    AuditDAO auditDAO = null;

}

Overall the control is inverted from old concept of coupled code to the frameworks like Spring which makes the object available. So that's IOC as far as I know and Dependency injection as you know when we inject the dependent object into another object using Constructor or setters . Inject basically means passing it as an argument. In spring we have XML & annotation based configuration where we define bean object and pass the dependent object with Constructor or setter injection style.

1) DI is Child->obj depends on parent-obj. The verb depends is important. 2) IOC is Child->obj perform under a platform. where platform could be school, college, dance class. Here perform is an activity with different implication under any platform provider.

practical example: `

//DI
child.getSchool();
//IOC
child.perform()// is a stub implemented by dance-school
child.flourish()// is a stub implemented by dance-school/school/

`

-AB

As for this question, I'd say the wiki has already provided detailed and easy-understanding explanations. I will just quote the most significant here.

Implementation of IoC

In object-oriented programming, there are several basic techniques to implement inversion of control. These are:

  1. Using a service locator pattern Using dependency injection, for example Constructor injection Parameter injection Setter injection Interface injection;
  2. Using a contextualized lookup;
  3. Using template method design pattern;
  4. Using strategy design pattern

As for Dependency Injection

dependency injection is a technique whereby one object (or static method) supplies the dependencies of another object. A dependency is an object that can be used (a service). An injection is the passing of a dependency to a dependent object (a client) that would use it.

IoC concept was initially heard during the procedural programming era. Therefore from a historical context IoC talked about inversion of the ownership of control-flow i.e. who owns the responsibility to invoke the functions in the desired order - whether it's the functions themselves or should you invert it to some external entity.

However once the OOP emerged, people began to talk about IoC in OOP context where applications are concerned with object creation and their relationships as well, apart from the control-flow. Such applications wanted to invert the ownership of object-creation (rather than control-flow) and required a container which is responsible for object creation, object life-cycle & injecting dependencies of the application objects thereby eliminating application objects from creating other concrete object.

In that sense DI is not the same as IoC, since it's not about control-flow, however it's a kind of Io*, i.e. Inversion of ownership of object-creation.

What is wrong in my way of explainning DI and IoC?

Related