Geeks With Blogs

News

Daniel Garcia Let's code something up!

Inversion of Control and Dependency Injection aren't brand new, but they date back to the late 80s. Anyway, these concepts are quite popular right now due to the close relation which mantains with Frameworks like Spring in Java or Unity in .NET.

Inversion of Control

The IoC (Inversion of Control) concept was first adopted by Martin Fowler, designer of the MVVM (Model View View-Model) design pattern. Fowler defined the concept on a informal way designating it as Hollywood Principle, which states the famous sentence "Don't call us, we'll call you."

The principle makes distinction between the concept of "library" and "framework", defining the first one as a simple set of classes, methods and functions that are invoked by the program flow and then return control to it (normal control) and the second one as a more abstract and elaborated design that, at some point, will invoke the code that the programmer is responsible for coding (inversion of control).

The example given by Fowler could not be more simple: a normal control sequence would be a simple console program in which the program is requesting data from the user and performing sequential operations (calculations, screen displaying...) when it receives responses. A program that applies an inversion of control, however, could be represented as a window composed of textboxes, labels and buttons. The Framework, in this case, expose a loop which is expected to detect the wiring of events, such as pressing a button, at which point the user code is executed. The Framework will invoke our code instead of doing the opposite operation.

Dependency Inversion Principle

The second concept is owed to another Software Engineering guru, Robert C. Martin, father of the Agile Software Development and the basic principles of the object-oriented programming, known as SOLID.

Two of these principles, in fact, served as the basis for another of them: the concept of Dependency Inversion:

  • Open/Closed principle: software entities must be open for their extension and closed for modification.
  • Liskov Substitution Principle: an object always can be replaced by an instance of a derived class without altering the behavior of the application, this is said, all the methods of a class must be present in all their derived classes, and these classes must be perform the father's role.

Based on these principles, Martin wrote an article in which develops the concept of Dependency Inversion Principle. This article establishes, roughly, that one of the major problems of software is the coupling, this is said, the dependence of classes between them.

According to Martin, classes of the upper modules should not lay on the classes of the lower modules: they should be based on abstractions. Similarly, lower-level classes should meet the same principle. Similarly, abstractions should not depend on the details, but are the details that should depend on abstractions.

Inversion concept comes, therefore, because the 180-degree rotation that occurs above the usual paradigm in which the upper modules tend to be built over the lower modules (for example, a user interface class invoking a method of an business class) and abstractions tend to depend on the details.

Dependency Injection

We come to the third concept in discord, related to the above two concepts : dependency injection . This concept is based on keeping a class "A" injecting objects into a class "B" instead of letting B being responsible for creating the object (this case is usually performed by a simple new(), using the default constructor) .

The most common way to perform dependency injection is through what is known as DI Container , which is responsible for performing the injection in simple objects ( POJOs and POCOs ). It is likely that after this brief explanation, someone may raise the question: "Ok, but... what's the relation between dependency injection and the jazz you gabbled in the previous two paragraphs?" The response to that question is that dependency injection is usually performed through some kind of Framework (Spring, Unity , Castle Windsor...) , so it will be perfmed through an inversion of control, making the Framework (specifically the DI Container) call the programmer's code.

The following example will illustrate the concept of dependency injection. Imagine you have the following code, which illustrates the "normal" operation of a class that depends on another :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public class Engine
{
    public void Accelerate()
    {
        // ...
    }
 
    public int GetRevolutions()
    {
        int currentRPM = 0;
 
        // ...
 
        return currentRPM;
    }
}
 
public class Vehicle
{
    private Engine m;
 
    public Vehicle()
    {
        m = new Engine();
    }
 
    public int GetRevolutionsEngine()
    {
        return m.GetRevolutions();
    }
}

As we can see, there is a class "Vehicle" which contains an object of the "Engine" class. The "Vehicle" class wants to get the engine revolutions, so it invokes the method GetRevolutions of the Engine object and returns its result. This case corresponds to a dependency (the top-class vehicle dependens on lower-class engine).

As a first step to decouple the engine from the vehicle we could make the "Vehicle" class leave in charge of instantiating the "Engine" object, passing it as a parameter to the constructor. Thus, the "Vehicle" class would be as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Vehicle
{
    private Engine m;
 
    public Vehicle(Engine vehicleEngine)
    {
        // The upper module doesn't instantiate directly the Engine object,
        // but it's passed as a parameter to the constructor
        m = vehicleEngine;
    }
 
    public int GetRevolutionsEngine()
    {
        return m.GetRevolutions();
    }
}

Simple, isn't it? The vehicle constructor is responsible for injecting the dependency within the object, preventing this responsibility to fall into the class itself. Thus, both objects are decoupled. If we use interfaces, the coupling will be even lower.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
public interface IEngine
{
    // Common methods to all engines
    void Accelerate();
    int GetRevolutions();
 
    void PerformAdmission();
    void PerformCompression();
    void PerformVent();
}
 
public class EngineGasoline : IEngine
{
    public void Accelerate()
    {
        PerformAdmission();
        PerformCompression();
        PerformExplosion();    // Only in gasoline engine
        PerformVent();
    }
 
    public int GetRevolutions()
    {
        int currentRPM = 0;
 
        // ...
 
        return currentRPM;
    }
 
    private void PerformAdmission()   { /* ... */ }
    private void PerformCompression() { /* ... */ }
    private void PerformExplosion()  { /* ... */ }
    private void PerformVent()     { /* ... */ }
 
}
 
public class EngineDiesel : IEngine
{
    public void Accelerate()
    {
        PerformAdmission();
        PerformCompression();
        PerformCombustion();   // Only in diesel engine
        PerformVent();
    }
 
    public int GetRevolutions()
    {
        int currentRPM = 0;
 
        // ...
 
        return currentRPM;
    }
 
    private void PerformAdmission() { /* ... */ }
    private void PerformCompression() { /* ... */ }
    private void PerformCombustion() { /* ... */ }
    private void PerformVent() { /* ... */ }
}
 
public class Vehicle
{
    private IEngine m;
 
    public Vehicle(IEngine vehicleEngine)
    {
        // The upper module doesn't instantiate directly the Engine object,
        // but it's passed as a parameter to the constructor
        m = vehicleEngine;
    }
 
    public int GetRevolutionsEngine()
    {
        return m.GetRevolutions();
    }
}

As we see, the Vehicle Object is not even attached to an object of class Engine. An object that implements the interface IEngine will be enough, like EngineGasoline and EngineDiesel . Then we can modify the vehicle by adding a property to access directly to the engine and invoke its methods.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class Vehicle
{
    private IEngine m;
 
    // Add a property to access to the engine
    public IEngine M
    {
        get { return m; }
        set { m = value; }
    }
 
    public Vehicle(IEngine vehicleEngine)
    {
        // The upper module doesn't instantiate directly the Engine object,
        // this is passed as a parameter in the constructor
        m = vehicleEngine;
    }
 
    public int GetRevolutionsEngine()
    {
        // Check that the engine exists before invoking one of its methods
        if (m != null)
            return m.GetRevolutions();
        else
            return -1;
    }
}

Finally, we will make the instantiation of the "Vehicle" object through a class that implements the Factory pattern . We'll define an enumeration to set the engine type that we want to have in our vehicle.

1
2
3
4
5
public enum EngineType
{
    GASOLINE_ENGINE = 0,
    DIESEL_ENGINE = 1
}

Now we'll create a class which will be responsible of instantiating the object.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class VehicleFactory
{
    public static Vehicle Create(EngineType type)
    {
        Vehicle v = null;
 
        switch(type)
        {
            case EngineType.DIESEL_ENGINE:
                v = new Vehicle(new EngineDiesel());
                break;
            case EngineType.GASOLINE_ENGINE:
                v = new Vehicle(new EngineGasoline());
                break;
            default:
                break;
        }
         
        return v;
    }
}

Therefore, we have managed to inject the dependency Engine inside the Vehicle object, causing the vehicle not depend on Engine. The Factory class (independent class to both elements) will be responsible for this work. For the programmer, the instantiation of the object won't be much more complicated, and he will instantiate the object in the following way:

1
Vehicle v = VehicleFactory.Create(EngineType.GASOLINE_ENGINE);

Instead this one

1
Vehicle v = new Vehicle();

Note that the difference is structural: the result is the same (a vehicle with an engine), but if in a future is necessary to extend the application (eg, if the client needs to work with an hydrogen-powered vehicle), it will be enough just to create a new class that implements the IEngine interface and adding the instantiation process inside the Factory class. Thus, there is no need to alter anything previously coded . If I have coded the "usual" way, it would require changes in the Vehicle class to implement this new functionality.

It remains in the pipeline the DI Container concept. In following posts I'll try to give a concrete example of this. Until then, stay tuned.

You can find the Spanish version of this article here.

Posted on Friday, January 17, 2014 4:45 PM .net , c# , IoC , inversion of control , DI , Dependency Injection | Back to top


Comments on this post: Inversion of Control and Dependency Injection

# re: Inversion of Control and Dependency Injection
Requesting Gravatar...
Not bad article but one very important error. That bit were you say the framework calls the programmer's code. That isn't correct unless you chose not to write the framework. And if you didn't chances are another programmer did. I say this because we are programmers and we develop programs using our own framework.
Left by Julian on Jan 19, 2014 10:28 AM

Your comment:
 (will show your gravatar)


Copyright © Daniel Garcia | Powered by: GeeksWithBlogs.net