An introduction to Dependency Injection (DI) and Inversion of Control (IoC)

There is so much confusion and arguing about what dependency injection is and whether is the same as inversion of control or just one form of it. If you are new to these terms it can be very confusing to say the least. I’ll try to describe what these are with some examples written in C# and hopefully you’ll have a better understanding of what this is and how to actually implement them in your code.

Dependency Injection (DI) vs. Inversion of Control (IoC)

According to Martin Fowler these two are exactly the same thing, here is some text extracted from his own article about inversion of control:

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.

Based on this I have personally settled on calling it all Dependency Injection which can be implemented in different forms. So, what is Dependency Injection? my definition of it? instead of having your classes creating a dependency or asking a factory object to make one for them, you pass the needed dependencies in to the constructor or via property setters, and your class doesn’t care about much else. This helps you to decouple dependencies that your classes are dependent on to do their work to make your code more flexible and testable.

For example, let’s say we have a booking service which we use to create a reservation object when a traveler books a hotel in a website. The reservation class might include things like validation and other business logic but it also calls code from another class to save the reservation details to a database. Here is an illustration of what I just described: mockup The photo above shows how the Reservation class depends on the ReservationDatabase class. In other words, Reservation knows that it needs a ReservationDatabase instance in order to be able to save the reservation details. The question to ask is, does the Reservation class really needs to know that it uses ReservationDatabase? It should be enough that Reservation class knows about the behavior, the methods, properties etc, of ReservationDatabase without knowing who actually implements that behavior. Let’s take a look at the code representation of the above:

public class Reservation
    {
        public void ProcessReservations(ReservationDetails reservation)
        {
            // business logic, validation, etc...

            // save booking to database
            new ReservationDatabase().Save(reservation);
        }
    }

Now, imagine if you wanted to test the code in the Reservation class, it wouldn’t work as in the example above uses an instance of ReservationDatabase which has the code to save the reservation to the database. In other words, you would need a database to test the code above. Also, the code above is not very flexible as it forces one class to know about the class that implements some of the code. For example, if you wanted to unit test the Reservation class you would need to test the code behind the Save method too as it is a method used in the code above. You cannot isolate your code using the implementation above.

Applying Dependency Injection

With dependency injection we can solve the potential problems we described above and with a few simple changes our code can be more flexible and testable. We can isolate our code and decouple our classes so one does not have to know the details of the other, just needs to know about the interface and not the class that implements it at run time. So how we do this? We can remove the dependency of Reservation on ReservationDatabase by extracting an abstract definition of the behavior used by Reservation in ReservationDatabase, in other words, let’s create an Interface to separate the two classes and ‘hide’ the implementation details of ReservationDatabase to the Reservation class. This is illustrated below: dependencyinjection In the illustration above, ReservationDatabase implements IPersist (interface) and Reservation uses it. At this point Reservation might still be using ReservationDatabase but it doesn’t know it, it just knows that is uses something that implements IPersist. We could change what happens in ReservationDatabase and the Reservation class wouldn’t know about it, or perhaps we could have a new class implement IPersist and again, Reservation wouldn’t know or care about it. Here is the code representation of the above, first you’ll see how Reservation now uses the new interface IPersist which is implemented by ReservationDatabase in our example:

public class Reservation
    {
        private IPersist _reservationDatabase;

        public Reservation(IPersist reservationDatabase)
        {
            this._reservationDatabase = reservationDatabase;
        }

        public void ProcessReservations(ReservationDetails reservation)
        {
            // business logic, validation, etc...

            // save booking to database
            _reservationDatabase.Save(reservation);
        }
    }

The code above shows you a basic implementation of Dependency Injection (DI), now let’s see how we benefit from this. The code above shows how we injected the dependency (IPersist) into our Reservation class by using a constructor. We did this by using what is called constructor injection, where we supply the IPersist instance to Reservation’s constructor, or property injection where we supply it to Reservation after it has been instantiated by setting a property on it.

This gives us the ability to use any code that implements IPersist without knowing the details of that code. For example, let’s say that we wanted to not only persist the reservation to the database but also to some XML document for whatever reason. With the updated code we would just need to write a new class that had all of the code to create a new XML document and then make sure that implements our interface IPersist. By doing this, our Reservation class will now be able to save the reservation data to XML without having to make any code changes in that class. See illustration below:

dependencyinjectionThe above illustration shows clearly how Reservation only needs to know about IPersist but it doesn’t know what other classes implement it, and that is OK. As you would imagine, we could keep adding classes to perform some sort of persistence without having to make a single change on Reservation, all we need to do is implement IPersist and we’ll be done.

Dependency injection in this example is what we showed in the code example above, notice how Reservation has a constructor which requires an instance of IPersist as a parameter. It stores this instance in a field and when invoked the last step of ProccessReservations method uses this injected instance to save the reservation.

I will write about Dependency Injection Containers / IoC Containers in a follow up post but for now, use the examples above as a basic way to implement Dependency Injection in your code to make it a bit more flexible and testable. Cheers!