Basic to Basics: What is Dependency Inversion? Is it IoC? Part 2

In my previous post on dependency inversion, I talked about what dependency inversion is and gave some examples in the real world.

This post is going to focus much more on the details and how it relates to code.

Back to your code…

Now let’s look at a code example to see how dependency inversion helps us out. Let’s say you are creating a high level module for parsing log files and storing some basic information into a database.

In this case you want to be able to handle several different log files from a number of different sources and write some common data they all share to a database.
One approach to this kind of problem is to have your module handle each kind of log file based on what kind of data and format it contains and where it is. Using this approach, in your module you would handle various kinds of log files based on the interface those individual log files present to you. (When I use interface here, I am not talking about the language construct, but the concept of how we interface with something.)

Using this approach, in our module we might have a switch statement or series of if-else statements that lead us to a different code path depending on what kind of log file we are processing. For one log file we might open up a file on disk, and read a line, then split that line based on some delimiter. For another perhaps we open a database connection and read some rows.

The problem is the log files are defining the interface our higher level code has to use. They are in effect “in control” of our code, because they are dictating the behavior our code must conform to.

We can invert this control, and invert the dependencies by specifying an interface that the log files we process must conform to. We don’t even have to use a language level interface.

We could simply create a data class called LogFile that is the input to our module. Anyone who wanted to use our module would first have to convert their files to our format.

We could also create an ILogFileSource interface that classes could implement to contain the logic of parsing log files from different sources. Our module would depend on ILogFileSource and specify what kind of methods and data it needs to parse the log files instead of the other way around.

The key point here is that our high level module should be controlling the interface (non language construct kind) that the lower level modules need to adhere to instead of being at the whim of the interfaces of each lower level module.

One way to think of this is that lower level modules provide a service to higher level modules. The higher level modules specifies the interfaces for that service and the lower level module provides that service.

room service thumb Basic to Basics: What is Dependency Inversion? Is it IoC? Part 2

One thing I want to point out in this example is that we knew there would be more than one log file source. If we were writing a log file parsing module that was only ever going to work against one source it might not be worth trying to invert this dependency because we wouldn’t see any benefit from doing so. It isn’t very hard for us to write out code as cleanly as possible working with one source and then refactor it later to invert the dependencies once we have additional sources.

Just because you can invert dependencies doesn’t mean you should.

In this case since we are always writing to a database, I don’t feel any particular need to invert our dependency on writing out the log files. However, there is some real value in encapsulating all of our code that interacts with the database into one place, but that is for another post.

Notice we haven’t talked about unit testing yet

 

You see the problem of dependency inversion and inversion of control has nothing specifically to do with unit testing.

Simply slapping an interface on top of a class and injecting it into another class may help with unit testing, but it doesn’t necessarily invert control or dependencies.

I want to use the log parsing example to illustrate my point. Let’s say we had created our log parser to have a switch statement to handle each type of log file, and now we want to unit test the code.

There is no reason why we can’t create IDatabaseLogFile, ICSVFileSystemLogFile, IEventLogLogFile and IAnNotReallyDoingIoCLogFile, pass them all into the constructor of our LogFileParser as dependencies and then write our unit tests passing in mocks of each.

That in an extreme example for sure, but the point is slapping an interface onto a class does not an IoC make.

We shouldn’t be trying to implement this principle to make it easier to write unit tests. Difficult to write unit tests should give us hints like:

  • Our class is trying to do too much
  • Our class has lots of different dependencies
  • Our class requires a lot of setup to do work
  • Our class is just like this other class that does the same thing only for a different input

All of these kinds of hints tell us that we might want to invert control and invert dependencies to improve the overall design of our class, not because it makes it easier to test. (Although it should also make it easier to test.)

Ok, ok, so is dependency inversion the same as inversion of control or what?

 

Short answer: yes.

It depends on what you mean by control. There are three basic “controls” that can be inverted.

  1. The control of the interface. (How do these two systems, modules, or classes, interact with each other and exchange data?)
  2. The control of the flow. (What controls the flow the program? This control inversion happens when we go from procedural to event driven.)
  3. The control of dependency creation and binding. (This is the kind of inversion of control IoC containers do. This inversion is passing the control of the actual creation of and selection of dependencies to a 3rd party which is neutral to either of the other 2 involved.)

Each of these 3 is a specific form of dependency inversion and may even involve multiple kinds of dependencies being inverted.

So when someone says “inversion of control”, you should be thinking “what control is being inverted here?”

Dependency inversion is a principle that we use in architecting software.

Inversion of control is a specific pattern that is applied to do so.

Most people only think of inversion of control as #3 above, inverting the control of dependency creation and bind. This is where IoC containers and dependency injection take root.

What can we learn from this?

My goal is that we stop grouping the concepts of inversion of control and dependency inversion automatically with dependency injection.

We have learned that dependency inversion is the core principle that guides many of the other practices that have derived from it.

Whenever we apply a pattern we should be looking for the core principle it is tied to and what problem it is helping us solve.

With this base understanding of dependency inversion and inversion of control, we have the prerequisite knowledge to look at dependency injection and understand better what specific problem it tries to solve. (Which I will cover in another post.)

As always, you can subscribe to this RSS feed to follow my posts on Making the Complex Simple.  Feel free to check out ElegantCode.com where I post about the topic of writing elegant code about once a week.  Also, you can follow me on twitter here.
  • Pingback: Basic to Basics: What is Dependency Inversion? Is it IoC? Part 1 « Making the Complex Simple()

  • Pingback: The Morning Brew - Chris Alcock » The Morning Brew #731()

  • Mark

    John,

    That was an excellent, clear and very helpful explanation of dependency inversion – thank you

    Mark

  • FrenkyB

    I have a question: I’ve created a project using entity framework as ORM. For entity framework I’ve set class library. Another class library is data layer which connects to entity framework library. I’ve also added project for testing my application and another project (Windows Forms) as my GUI. My question is: in order to show info on the GUI I must reference both data layer and EF. Is this OK or this means too much dependencies? Rerefencing EF from GUI is just because of showing some data types that are defined by entity framework and comes to GUI layer as List.

    • http://simpleprogrammer.com jsonmez

      One way to avoid having your GUI layer depend on EF layer is to use DTO or Data Transformation Objects. Basically just classes that look like the same types in the EF layer, but you copy into a new type in the data layer. This would insulate your GUI code from depending on the EF layer code. There are some frameworks for making this easy like Automapper (https://github.com/AutoMapper/AutoMapper.)

      It really depends on if you feel you need to isolate from EF. Some might argue that you shouldn’t worry about it because you are not going to change out your data persistence layer, but it really is up to you.

  • FrenkyB

    Thanks for answer, nice tool Automapper )) As far as I’ve used it I see only a little performance problem: when I get the list of my objects from EF, I need to map each object to my type of objects. Otherwise the tool is great, I can map easily from EF to classes that are created on data layer. Sometimes I think that follow 100% rules of dependency injection is not possible or it’s not that wrong if you make a reference to – in my case – entity framework library in the GUI layer as long as you use that reference just to show types defined there. After all how (in)dependent modules are can be best shown if you change one module – in my case I need my app to work with MVC and Windows Forms. So I will have to implement both GUI’s. For now I have just Windows Forms.

  • http://www.facebook.com/budgie.mitchell Budgie Mitchell

    Martin Fowler says here:

    http://martinfowler.com/articles/injection.html

    “As a result I think we need a more specific name for this
    pattern. Inversion of Control is too generic a term, and thus people
    find it confusing. As a result with a lot of discussion with various
    IoC advocates we settled on the name Dependency Injection.”

    So, if he says “IoC = Dependency Injection” we should go along with Fowler, yes? My head hurts.

    • jsonmez

      I read this a few times when researching this article. As well as what Bob Martin had to say.

      IMO, it comes down to this.

      IoC is a concept. You can invert control in many different ways. In that same article. Martin Fowler asks the question “what control are they inverting?”

      Dependency injection is one form of IoC. It just happens to be the most common.

      The naming and confusion has made this really bad, and to some degree it doesn’t matter all that much.

      We basically end up with 3 things.

      1. Dependency Inversion Principle

      2. IoC

      3. Dependency Injection

      Dependency inversion principle is just the idea that you can reverse dependencies.

      IoC is just the idea that the actual control of the system can be inverted, through a mechanism like applying the DIP or using Dependency Injection with IoC containers.

      Dependency Injection is a concrete way of applying DIP and IoC. It means to actually inject the dependencies of a class into it.

      The only reason I think the difference is somewhat important is because many developers think “oh, IoC, DIP, that is all just Dependency Injection.” And, they miss out on other ways to apply the important concept of IoC and what we are really trying to do.

      Sure, you can use an IoC container to do dependency injection, but why? You can’t answer why unless you understand the principles behind it.

      • http://www.facebook.com/budgie.mitchell Budgie Mitchell

        From what I read IoC is also about frameworks, the “don’t call us we’ll call you” principle.

        When I read that, I think of a framework like ASP.NET which allows us to plumb in our code when something happens (e.g. Control.OnPreRender(), Control.OnRender() and other overridables) – the framework calls our code when it needs to.

        It’s not helpful for so many definitions to be out in the wild, in fact it’s doing my bloody head in! I despair. What should be simple things are being trumped-up to sound esoteric and advanced computing science when they do not need to be, IMHO (this applies to Liskov substitution principle as well)

        • jsonmez

          I agree with you. Too many definitions. But, it is a history we can’t avoid at this point.

          I did a Pluralsight course on IoC that covers all of this in depth, because I wasted to make everything perfectly clear: http://psight.me/ps-ioc

          A lot more than what I can type out here.

          But, you bring up some great points.

          • http://www.facebook.com/budgie.mitchell Budgie Mitchell

            If the authors of the terms followed their own advice to KISS then we wouldn’t be in this mess, dont you agree? There are many developers running about (me included) thinking they are object oriented experts when in fact their knowledge is lacking or their understanding of a particular paradigm (hate that word) is plain wrong.

          • http://www.facebook.com/budgie.mitchell Budgie Mitchell

            BTW I’ll check out your course also :)

          • jsonmez

            Yep, you are absolutely right. That is one of the reasons why I started this blog… To try and make the complex simple.
            IMO, for the most part, if it isn’t simple, it’s wrong.