Dependency Injection in C++

My apologies on the double post – I accidentally clicked “create new page” :0)

A really valuable technique birthed in the Java world is the idea of dependency injection. That is, instead of a class having to create it’s own object:

class Foo {

public Foo(){

bar = new Bar();

}

private Bar bar;

}

(forgive my Java, it’s been awhile.)

You pass in the object in its constructor, like this:

…

public Foo(Bar newBar) { bar = newBar; }

…

Of course, then, someone else has to be responsible for creating the bar object, so really, you end up just passing in object factories, or having a factory do all your setup for you.

(The passing in of object factories case):

interface BarFactory {

public Bar BuildBar();

}

class NormalBarFactor implements BarFactory {

public Bar BuildBar() { return new Bar(); }

}

class TestBarFactory implements BarFactory {

public TestBar BuildBar() { return new TestBar(); } //where TestBar inherits from Bar…

}

class Foo {

public Foo(BarFactory barFactory) { bar = barFactory.BuildBar() }

}

(And in the object configuration factory way…)

class Foo {

public Foo(Bar newBar) { bar = newBar; }

}

class FooBuilder{

public Foo BuildFoo() { return Foo(new Bar()) };

}

class TestFooBuilder{

public Foo BuildFoo() { return Foo(new TestBar()); }

}

As you can see, either of these approaches is really just variations on a theme. The idea is that Foo, until runtime, does not know what kind of Bar it is using. This provides two major benefits, one, as you can see above, it eases testing. We can create test versions of objects, called “Mock Objects” to pass into the class we want to test. These mock objects are simplified versions of objects that the tester controls very closely, making it easier to test Foo in isolation. Additionally, with our mock objects being an example of this, this approach also allows infinitely configurable objects. This greatly increases reusablility of anything we build, and instead of going the old way of creating yet another object per configurable item, we instead just create the basic underlying class generically and plug in it’s dependencies when we need one.

For instance, if we needed a single threaded Foo and a multithreaded Foo, pure object inheritance and old style object oriented design might tell us to have both types of Foo inherit from some interface, and we differ their threading behavior based on the two implementations. But now what if we have another variation in Foo’s, maybe we have one that is designed to deal with a certain protocol – say, deal with information coming in from the web, while another Foo is designed to deal with information coming in from a local database. Now, really, we have to build 4 foos, a single threaded internet one, a single threaded database one, a multithreaded internet one, and a multithreaded database one. Vary security policies, memory management issues, and other things, and you can see how object hierarchies can explode with what might be called “cross-cutting concerns.”

Using dependency injection solves this, by creating only one Foo object and allowing the caller to vary the threading policy or data sink independently, as needed. This is also called the “Bridge Pattern”, among other things. If you belong to the camp that claims patterns are simply proof of missing language features, then the Bridge Pattern might be seen as an object-oriented ‘solution’ to the problems solved by what’s called Aspect Oriented Programming, however, we’re not going to get into that right now.

There are some minor downsides to this approach, as it incurs a runtime penalty as all these polymorphic objects are created, and the caller must also know a little more about the object its creating – breaking encapsulation, to a degree. Additionally, more overhead is required as a bunch of boilerplate factory objects need to be created.

For C++, you can use the exact same solution – pass in factory objects to another object’s constructor and then use the factory to configure the constructed object at runtime. The same upsides and downsides exist. However, luckily, with the use of templates, there is a better way. The “factory” pattern used in dependency injection, if again, you belong to the camp that believes patterns are proof of missing language features, could be seen as an object-oriented solution to treating classes and types as first class objects. That is, to say, in some languages, you cannot directly pass Types around by themselves, as arguments. In languages that you can, such as via C++’s templates, the factory pattern disappears.

How does this affect dependency injection? Well, since dependency injection, and the bridge pattern, make very heavy use of the factory pattern, it simplifies these two approaches a great deal. And while pure aspect-oriented programming is still beyond C++’s reach, clever use of templates brings you very close. I guess you could say that using templates to solve the bridge pattern is providing a generic solution to an aspect problem, rather than an object solution to an aspect problem.

To do “generic dependency injection”(GDI), which I’ll differentiate from “object dependency injection”(ODI) from here on out, in C++, you still go through the same mental processes in ODI to find the classes that you think may vary, or in the case of testing, you want to isolate your object from to test for.

class Foo {

public:

Foo() { bar = new Bar() }

private:

Bar * bar;

};

In the above, like our Java example, this class is still the Bar class. We don’t want the Bar class to be coupled with our Foo class, which it currently is, but we don’t want the overhead of building all those object factories either. And before anyone complains – yes, I know I left out the freeing of bar in the destructor, and moreover, it would have probably been easier just to make bar a value instead of a pointer, or used boost::shared_ptr. We’ll be leaving out those details for simplicity.

Once we’ve recognized that Bar and Foo are coupled, we’ll pull out the Bar type into a template, rather than having Foo know about it.

template<typename BarType>

class Foo {

public:

Foo() { bar = new BarType() }

private:

BarType * bar;

}

Voila, now in our release code, we simply create Foo like this:

Foo<Bar> …

and in our test code, we create Foo like this:

Foo<TestBar> …

Our Foo object is completely decoupled from the type of Bar it’s using, at compile-time. This increases runtime efficiency but maintains strict typechecking. If you’re a fan of “Modern C++ Design”, you’ll see that we’re co-opting “Policy based design” for testing purposes. Policy Based design is the proper name for using templating to solve the bridge pattern in general, of which GDI for testing is a specific application.

I’ll be talking more about this subject in the future, some of its drawbacks and some potential solutions. Namely, what happens now for the object that needs to create a Foo? Does it now need to know which Bar it wants Foo to use? It used to simply be able to create a Foo(), now it has to fulfill a template argument. Luckily, with some template tricks, we can use functional techniques to make this not the case. I’d also like to discuss the strengths GDI has over ODI, namely, that it’s use of types falls far closer to “Duck Typing” found in languages like Python, but unlike Python, we still keep strict typechecking. Finally, I’d also like to talk about some specific C++ strengths that good templating and use of RAII have in the relm of unit testing.