Dependency Injection: Turtles all the way down?

The examples you provide do not use Dependency Injection. Instead, Bar should use Constructor Injection to get a Foo instance, but there’s no point in injecting a concrete class. Instead, you should extract an interface from Foo (let’s call it IFoo) and inject that into Bar:

public class Bar
{
    private IFoo f;

    public Bar(IFoo f)
    {
        this.f = f;
    }

    public int doSomethingWithFoo
    {
        int x = this.f.doSomethingWithExternalDependency();
        // Do some more stuff ...
        return result;
    }
}

This enables you to always decouple consumers and dependencies.

Yes, there will still be a place where you must compose the entire application’s object graph. We call this place the Composition Root. It’s a application infrastructure component, so you don’t need to unit test it.

In most cases you should consider using a DI Container for that part, and then apply the Register Resolve Release pattern.

Leave a Comment