What is Inversion of Control?

design-patterns, inversion-of-control, language-agnostic, oop, terminology

Solution

The `Inversion-of-Control` (IoC) pattern, is about providing any kind of `callback`, which "implements" and/or controls reaction, instead of acting ourselves directly (in other words, inversion and/or redirecting control to the external handler/controller). The `Dependency-Injection` (DI) pattern is a more specific version of IoC pattern, and is all about removing dependencies from your code.

Every `DI` implementation can be considered `IoC`, but one should not call it `IoC`, because implementing Dependency-Injection is harder than callback (Don't lower your product's worth by using the general term "IoC" instead).

For DI 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 control over which `SpellChecker` implementation to use because we're injecting the dependency into the `TextEditor` signature.

Note that just like IoC being the base of many other patterns, above sample is only one of many Dependency-Injection kinds, for example:

- Constructor Injection.

Where an instance of `IocSpellChecker` would be passed to constructor, either automatically or similar to above manually.

- Setter Injection.

Where an instance of `IocSpellChecker` would be passed through setter-method or `public` property.

- Service-lookup and/or Service-locator

Where `TextEditor` would ask a known provider for a globally-used-instance (service) of `IocSpellChecker` type (and that maybe without storing said instance, and instead, asking the provider again and again).

Problem

Inversion of Control (IoC) can be quite confusing when it is first encountered. - What is it? - Which problem does it solve? - When is it appropriate to use and when not?

Original source