July 11, 2020

What is IoC and DI?

Inversion of Control

Inversion of Control (IoC) - objects don't create other objects on which they rely to do their work. Instead, they get the objects that they need from an outside source (for example, an XML configuration file).

The Inversion of Control (IoC) and Dependency Injection (DI) patterns are all about removing dependencies from your code.

For example, say your application has a text editor component and you want to provide spell checking. Your standard code would look something like this:

public class TextEditor {

    private SpellChecker checker;

    public TextEditor() {
        this.checker = new SpellChecker();
    }
}

What we've done here creates a dependency between the TextEditor and the SpellChecker. In an IoC scenario we would instead do something like this:

public class TextEditor {

    private IocSpellChecker checker;

    public TextEditor(IocSpellChecker checker) {
        this.checker = checker;
    }
}

In the first code example, we are instantiating SpellChecker (this.checker = new SpellChecker();), which means the TextEditor class directly depends on the SpellChecker class.

In the second code example, we are creating an abstraction by having the SpellChecker dependency class in TextEditor's constructor signature (not initializing dependency in class). This allows us to call the dependency then pass it to the TextEditor class like so:

SpellChecker sc = new SpellChecker; // dependency
TextEditor textEditor = new TextEditor(sc);

Now the client creating the TextEditor class has to control over which SpellChecker implementation to use because we're injecting the dependency into the TextEditor signature.

Dependency Injection

Inversion of Control is a more general concept and Dependency Injection is a concrete design pattern.

Dependency injection generally means passing a dependent object as a parameter to a method, rather than having the method creates the dependent object. It's a very useful technique for testing since it allows dependencies to be mocked or stubbed out.

What is means in practice is that the method does not have a direct dependency on a particular implementation. Any implementation that meets the requirements can be passed as a parameter.

Dependencies can be injected into objects by any means (such as constructor injection or setter injection). One can even use specialized dependency injection frameworks (e.g. Spring) to do that, but they certainly aren't required. You don't need those frameworks to have dependency injection. Instantiating and passing objects (dependencies) explicitly is just as good an injection as an injection by the framework.

IoC in Spring

The simple meaning of inversion of the control means that now the framework, Spring is responsible for creating objects, wiring dependencies, and managing their life-cycle instead of a developer, which was the case before. That's where control is inverted from developer to framework.