Dependency Injection – Dependency Chain Pattern

architectural-patternsdependency-injection

On my last large project, I used dependency injection really heavily. I started out using constructor injection but even two or three dependencies resulted in really ugly code.

public MyClass(
    IDependency1 dependency1, 
    IDependency2 dependency2
    IDependency3 dependency3)

I am not a fan of property injection. Some people say it implies an "optional" dependency. I think what they mean is that there will be a default dependency (the production class) but it can be replaced with a mock object during test. Many times, my dependencies have dependencies, too, so I can't provide a default value unless I used a singleton or something. My problem with property injection is that I prefer fully initialized objects and don't want to accidentally forget to mock out a dependency during test.

So, I found a compromise. I created a "parameter object" that had properties for all of my dependencies. I passed these to my constructors. This had the benefit of keeping my code somewhat cleaner and I could ignore some dependencies during test if they weren't touched.

Based on feedback I got the impression this was a bad idea. It was constructor injection or parameter injection – no compromise allowed. Later I realized that these parameter objects sometimes became their own classes (or set of classes).

That's when I discovered an interesting pattern. Many business objects depended on other business objects, which had their own dependencies. What I ended up with was an interesting data structure, similar to a linked list.

A Simple Depedency Chain

This data structure could become fairly complex depending on the number of interacting classes. In most cases, the structure was closer to an n-ary tree. Each parameter object could link to any number of other objects (including other business objects). The business objects were the nodes of the tree and the parameter objects were like the edges connecting them.

A Complex Dependency Tree

I think connecting all these objects together without using a declarative dependency injection framework would be mind-numbing. The dependency injection framework I was using was going 8 levels deep in my code building the dependencies from the bottom up in the worst case.

The parameter objects usually just exposed the dependencies. On rare occasions, I would hide them behind friendly function calls and made them their own business objects (usually resulting yet another parameter object). I had to remind myself that the parameter objects only existed because I didn't want to construct dependencies in the constructor (or pass them to the constructor). It only made sense to create new business objects when I started repeating myself. Even then, I ended up with an explosion of parameter objects.

I've read plenty of books explaining that this situation should never happen. Classes should have very few dependencies. It was a sign that my classes did "too much". But in most of these cases, a business object used data from multiple database tables (repositories), configuration settings, services, etc. in order to calculate something. This occurred most often when implementing a series of steps making up a unit of work. When N things are needed to do a task, the best you can do is push those N things to other classes or on up the call stack. Is one class with 6 dependencies better or worse than 3 classes with two dependencies each?

I am hoping to get some feedback on this approach to dependency injection – in how it relates to architecting a business layer.

Best Answer

IMHO creation of "complete" classes via constructor has always been appealing, however setter injection requires a no-arg constructor, allowing pre-conditions (e.g. assertions) to be a reasonable alternative to guarantee "completeness" in the context of DI containers.

To me it is a trade-off between adding complexity versus implementing a simple, pragmatic, solution. And simplicity always wins.