In part 3 of this series of articles I discussed dependency injection in general terms. To understand what the CAB is doing for you it’s important to have an understanding of dependency injection, and I will be talking more about it in part 5.
This short article is something of an aside however, and is not critical for an understanding of the CAB. Here I will discuss two concepts that sound similar: inversion of control (‘IoC’) and dependency inversion. I will also discuss how both relate to dependency injection.
‘Inversion of Control’
‘Inversion of Control’ is currently something that everyone agrees is a good thing, even though no-one seems to be able to agree exactly what it is. For example, on Wikipedia there’s no definition of Inversion of Control, only an admission that we can’t define it.
Inversion of control is closely related to dependency injection, as I will describe below, and is often used synonymously with it. However, it has a wider meaning, and is arguably not strictly accurate when applied to dependency injection as an abstract concept. Martin Fowler discusses inversion of control at length, but in his article on dependency injection decides to avoid the term.
Inversion of Control in Relation to Frameworks
The conventional definition of inversion of control relates to frameworks and code re-use. Normally to re-use someone else’s code you would call into a library. You do this all the time in the .NET framework. For example, if you call Math.Tan() you are using someone else’s code, but you make the call and you have control.
However, there are times using .NET when the framework calls you back. An example is when you write a custom array sort algorithm using the IComparable or IComparer interfaces. Another is when you implement a custom enumerator by implementing IEnumerable on a collection class. In these cases the usual direction of control is inverted: something else is calling your code, rather than you calling something else.
If we implement IComparable on a class we have to write a method called CompareTo(). This defines when one object of the class’ type is bigger than another. Then when we call Array.Sort on an array of objects of this class the framework itself calls our routine to sort the objects according to our definition.
Here the .NET framework is calling my code, and as a result I have to write it with a specific method signature – int CompareTo(object obj). I don’t have direct control over when this call is made. We can think of this as an ‘inversion’ of ‘control’ from the Math.Tan example.
For obvious reasons, the inversion of control concepts described above are often called the ‘Hollywood Principle’, or ‘don’t call us we’ll call you’.
Inversion of control is discussed in relation to frameworks in ‘Design Patterns: Elements of Reusable Object-Oriented Software’ by Gamma, Helm, Johnson and Vlissides (also known as the ‘Gang of Four’ book). They summarize quite nicely:
“Frameworks emphasize ‘design reuse’… Reuse on this level leads to an inversion of control between the application and the software on which it’s based. When you use a toolkit (or a conventional subroutine library for that matter), you write the main body of the application and call the code you want to reuse. When you use a framework, you reuse the main body and write the code it calls. You’ll have to write operations with particular names and calling conventions, but that reduces the design decisions you have to make.”
Inversion of Control and Dependency Injection
So how does inversion of control relate to dependency injection? At first glance the concepts above and my examples in the previous article have little in common. Yet the two terms are often used synonymously. Indeed I have some course notes from a major computer trainer that actually says ‘IoC and dependency injection are terms that mean the same thing’.
The answer is that dependency injection is usually done via a framework of some kind. I will discuss this more in part 5, but typically you define your classes and then tell the framework to ‘inject’ them into other classes in some way. The framework is then calling back your code to do the injection, and we have inversion of control as described above.
Inversion of Control = Dependency Injection?
As I’ve discussed, dependency injection is just one very specific example of how inversion of control can be used. As a result it is probably wrong to treat IoC and dependency injection as terms that mean the same thing. IoC is a wider concept.
However, in spite of it not strictly being accurate, when people talk about ‘IoC Containers’ and ‘IoC Frameworks’ what they usually mean are containers or frameworks that do dependency injection.
Inversion of Control and the CAB
The Composite Application Block really is an inversion of control framework in all senses by the way. It allows us to do dependency injection, as I’ll describe below (eventually). It also is often calling us rather than us calling it. An example of this is the call to the ‘Load() method in a ModuleInit class at start up that we saw in Part 1 of this series of articles. We have to just know that method will be called when the module starts, and code to the method signature.
A related concept that causes further confusion is dependency inversion. Once again dependency inversion is a wider concept that is used in dependency injection. The aim of dependency inversion is to prevent high-level classes directly depending on lower-level classes and thus introducing tight-coupling between them. Instead we get both sets of classes to depend on interfaces.
Dependency Inversion in the Example from Part 3
Consider my example of a main class and dependent classes from part 3. If you were writing this example in a ‘traditional’ way you might have the client code (class Program) create the MainClass which in turn would decide which dependent class it needed and instantiate it. The dependencies between classes would look something like this:
As we know, direct dependencies between classes are in general a bad thing as they make it harder to change the code in the dependent classes. So in our dependency injection pattern we introduce a specific interface that all our classes depend on in some sense:
Now, as discussed previously, the code is less brittle as we can change the dependent classes without worrying too much about breaking MainClass, as long as we don’t change the interface.
Dependency Inversion and Inversion of Control
We have inverted the dependencies for the dependent classes here. Previously they were being referred to directly by MainClass. Now nothing refers to them directly, instead they refer to the interface. The arrows from the dependent classes now point up instead of down.
Note that this is NOT inversion of control. We are inverting dependencies between classes. This is not an example of a framework calling the code rather than the code calling the framework. In both cases here ultimately MainClass calls code that runs in a dependent class.
After the fairly lengthy discussion of dependency injection and inversion of control in the last two parts of this article I will return to discussing the CAB in part 5.
Many code design books make a clear distinction between the dependency inversion I have described in this section and full ‘inversion of control’ (the Hollywood principle). For an example see the excellent ‘Head First Design Patterns’ book:
As mentioned, Wikipedia is as confused as everyone else about IoC:
Martin Fowler is of course excellent on the subject:
The Gang of Four book discusses Inversion of Control in a section on frameworks: