There is a guy I’m working with who is trying to wrap his head around design principles. He’s been watching a lot of PluralSight videos. As he was processing information about Inversion of Control, he asked the natural question I’ve never actually considered before. “Why is it called Inversion of Control? Normally, when you talk about ‘Inversion’ you are talking about reversing something or negating something. That isn’t what we are doing here.”
What Is Inversion of Control?
So, let’s start with a definition of what Inversion of Control is. And let’s start the definition by explaining what it isn’t.
In the old days, back when I started programming. We had this thing called “Procedural Programming.” Control of your application flowed from beginning to end with looping to take care of any kind of waiting that needed to take place. Martin Fowler describes this using an illustration that is version similar to a basic “How to program in C#” console application that is in the beginning of most beginner programming books.
Let’s consider a simple example. Imagine I’m writing a program to get some information from a user and I’m using a command line enquiry. I might do it something like this#ruby puts 'What is your name?' name = gets process_name(name) puts 'What is your quest?' quest = gets process_quest(quest)
In this interaction, my code is in control: it decides when to ask questions, when to read responses, and when to process those results.
What Inversion of Control does is that it puts something other than the main code in charge of doing critical parts of the program so that those other parts of the program can be swapped out by the person implementing the code.
Examples of Inversion of Control
If you’ve ever written a WebForms or Windows Forms application, you’ve already experience inversion of control.
OnPageLoad() or OnFormLoad()
You have probably never even given this much thought. You think these two methods are where your code starts. But the reality is, the code started long before these methods ever got called. The thing that is in control is the .NET framework. You’ve created a delegate that gets called by the framework so that your page or form does what you want it to. Without this inversion of control, you would have to write a whole lot more code.
While you might think of OnPageLoad and OnFormLoad as event handlers, the way they are implemented are more like virtual functions. Event handlers, on the other hand, are a specific type of delegate that say, “When this thing happens, let me know about it.” The code that fires the event doesn’t even really care what you do during the event. Again, the control has been “Inverted” because there is a lot of code that is running that you have no control over and probably have no knowledge of.
One of my favorite methods of inverting control is to use virtual functions. I can have a parent class that controls the flow of the program that calls various virtual functions in order. But my child class can provide the implementation of the functions to make them do various things. I used this, at one time in the past, to create a framework for submitting links to various bookmarking sites. They all worked essentially the same way, all I had to do was implement the specific details for each site while 80% of my code stayed the same in the base class.
Delegates or Callback Functions
I’ve talked about Dependency Injection before. Again, it is another way of delegating control to something other than the code that has main control. What I want to make special note of here, though, is that Inversion of Control is not Dependency Injection but Dependency Injection is a form of Inversion of Control. I think this is where most of the confusion about Inversion of Control comes from. Most of the literature that talks about Inversion of Control talks about it at the same time they are talking about Dependency Injection. As though the two concepts were the same.
Why Inversion of Control Matters
Finally, I want to talk for a bit about why Inversion of Control matters. Because, for me, it is a lot more important that we understand what we are trying to achieve than it is that we’ve given it the right name or that we even know what name to call it. All of the examples I’ve provided are things you’ve probably done in your code. Some of them you’ve done without even knowing you were doing them. But think about the alternative of not doing them.
First, your code would be a lot harder to maintain. Just think of how hard it would be to write a web site and maintain it if you had to write code that handled all of the work that happens for you behind the scenes.
Second, it makes the code more loosely coupled. And by doing that, it makes the code testable AND it makes the code more flexible and easy to change in the future.
Maybe instead of calling it Inversion of Control it should have been called Delegation of Control. Either way, the concept is to remove as much code as possible from our main controlling code and give the implementation responsibility to something else that can be swapped in without having to change the main loop.
Other Places Talking About Inversion of Control:
- Inversion of Control
- Design Patterns
- Martin Fowler on IoC
- Inversion of control, dependency Injection, service oriented programming?
- Inversion of Control and Dependency Injection
- Inversion of Control is NOT about testability
Other post in Software Architecture
- Software Architecture without Test Driven Development is DANGEROUS! - January 29th, 2015
- Why Is It Called “Inversion of Control”? - June 11th, 2015
- Are You Thinking Clearly About Your Architectural Choices? - September 17th, 2015
- 4 Reasons to Write Loosely Coupled Code - September 27th, 2016