Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I've seen several recommend use of IoC containers in code. The motivation is simple. Take the following dependency injected code:

class UnitUnderTest
{
    std::auto_ptr<Dependency> d_;
public:
    UnitUnderTest(
        std::auto_ptr<Dependency> d = std::auto_ptr<Dependency>(new ConcreteDependency)
    ) : d_(d)
    {
    }
};


TEST(UnitUnderTest, Example)
{
    std::auto_ptr<Dependency> dep(new MockDependency);
    UnitUnderTest uut(dep);
    //Test here
}

Into:

class UnitUnderTest
{
    std::auto_ptr<Dependency> d_;
public:
    UnitUnderTest()
    {
        d_.reset(static_cast<Dependency *>(IocContainer::Get("Dependency")));
    }
};


TEST(UnitUnderTest, Example)
{
    UnitUnderTest uut;
    //Test here
}

//Config for IOC container normally
<Dependency>ConcreteDependency</Dependency>

//Config for IOC container for testing
<Dependency>MockDependency</Dependency>

(The above is hypothetical C++ example of course)

While I agree that this simplifies the interface of the class by removing the dependency constructor parameter, I think the cure is worse than the disease for a couple of reasons. First, and this is a big one for me, this makes your program dependent on an external configuration file. If you need single binary deployment, you simply cannot use these kinds of containers. The second issue is that the API is now weakly and worse, stringly typed. The evidence (in this hypothetical example) is the string argument to the IoC container, and the cast on the result.

So.. are there other benefits of using these kinds of containers or do I just disagree with those recommending the containers?

share|improve this question
    
The sample code looks like a really bad example of an IoC implementation. I'm only familiar with C# but surely there is a way to have constructor injection and programmatical configuration in C++ as well? –  rmac Sep 3 '11 at 13:19

3 Answers 3

up vote 10 down vote accepted

In a large application with many layers and lots of moving parts, it's the drawbacks that start to look pretty minor in comparison to the advantages.

The container does "simplify the interface" of the class, but it does so in a very important way. The container is a solution to the problem that dependency injection creates, which is the need to pass dependencies all over the place, down through object graphs and across functional areas. You have one small example here that has one dependency - what if this object had three dependencies, and the objects that depended on it had multiple objects that depended on them, and so on? Without a container, the objects at the top of those dependency chains end up becoming responsible for keeping track of all of the dependencies in the entire application.

There are different kinds of containers, as well. Not all of them are stringly typed, and not all of them require configuration files.

share|improve this answer
3  
But a large project makes the problems I already mentioned worse. If the project is large, the configuration file becomes a huge dependency magnet itself, and it becomes even easier to have one typo lead to undefined behavior at runtime. (i.e. having a typo in the config file would cause the cast to cause undefined behavior if the wrong type gets returned). As for dependencies of dependencies, those don't matter here. Either the constructor takes care of making them, or the test is going to be mocking out the top level dependency. –  Billy ONeal Feb 22 '11 at 18:06
    
... Continued ... When the program isn't being tested, the default concrete dependency gets instantiated at each step. W.r.t. other kinds of containers, do you have some examples? –  Billy ONeal Feb 22 '11 at 18:07
2  
TBH I don't have tons of experience with DI implementations, but take a look at MEF on .NET, which can be but doesn't have to be stringly typed, has no config file, and concrete implementations of interfaces are "registered" on the classes itself. BTW, when you say: "the constructor takes care of making them" - if that's what you're doing (aka "poor man's constructor injection"), then you don't need a container. The advantage of a container over doing that is that the container centralizes information about all those dependencies. –  nlawalker Feb 22 '11 at 21:01
    
+1 for that last comment -- the last sentence there is the answer :) –  Billy ONeal Feb 23 '11 at 2:17
    
Note -- I'm checkmarking this answer, but I'm not checkmarking it for the content of the answer (because that I think is drivel). However, the comment two comments above this one is an excellent answer. –  Billy ONeal Apr 1 '11 at 2:54

The Guice IoC framework from Java do not rely on a configuration file but on configuration code. This means that the configuration is code no different from the code making up your actual application, and can be refactored etc.

I believe that Guice is the Java IoC framework which finally got configuration right.

share|improve this answer
    
Are there any similar examples for C++? –  Billy ONeal Feb 22 '11 at 20:58
    
@Billy, I am not familiar enough with C++ to be able to say. –  user1249 Feb 22 '11 at 21:56

This great SO answer by Ben Scheirman details some code examples in C#; some advantages of IoC containers (DI) being:

  • Your dependencies chain can become nested, and it quickly becomes unwieldy to wire them up manually.
  • Enables use of Aspect oriented programming.
  • Declarative & nested database transactions.
  • Declarative & nested Unit of work.
  • Logging.
  • Pre/Post conditions (Design by Contract).
share|improve this answer
1  
I don't see how any of those things can't be implemented with simple constructor injection. –  Billy ONeal Apr 17 '12 at 17:59
    
With a good design, constructor injection or another method may be enough for you; the advantages of these IoC containers might be only in specific cases. The example given with INotifyPropertyChanged in a WPF project was one such example. –  dodgy_coder Apr 18 '12 at 0:54

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.