Too Much of a Good Thing? Constructor Injection Overload
This week there have been two posts covering dependency inversion and going too far with constructor injection. In the first post Robert C Martin (Uncle Bob) cautions against littering your code with calls to your IoC container.
I think these frameworks are great tools. But I also think you should carefully restrict how and where you use them.
The post goes on to discuss how to keep the code which builds dependencies contained in one place so that you are not littering your code with calls to the container framework or coupling yourself to other classes using new() statements.
The second post by Jeffrey Palmero takes this a little further and is the one that really got me thinking. Palmero sets up an example where a class requires two interface dependencies in its constructor. However, in the code, both dependencies are not always used. This was a key thing to note, because Palmero’s point was,
The anti-pattern is that one of these constructor arguments is really not a class dependency.
In his example, one of the interface dependencies required in the constructor is only used in some cases. This was a huge “duh” for me because I know there are several times when I have required everything the class might use in the constructor.
I think the key here is balance. Require the real dependencies up front, but also allow for other dependencies to be resolved by blending the use of a container with a factory type pattern. Keep all the dirty details of your dependent objects and how they are resolved hidden and encapsulated in one place. This would allow you to switch containers or stop using one all together.
** Update **
A couple readers have posted comments and I would love to hear more. Be sure to give them a read!
No trackbacks yet.
Comments are closed.



January 21, 2010 - 8:13 am
Perhaps it’s just my limted personal experience with IoC, but I’m not convinced (yet) that making my classes more complex by adding calls to factories that abstract away calls to service locators (or worse, making my classes depend directly on the IoC containers themselves) is all that much better than a few extra parameters being passed into a constructor. Perhaps another valid approach would be to consider why the class has so many different contexts that not all of the dependencies are used in every case and refactor it down to multiple classes. In the end, I’m sure there are cases where both approached make sense – thanks for pointing out the design consideration!
January 21, 2010 - 8:18 am
You bring up another good point that has been on my mind too — how many dependencies is too many? Because some class has to be responsible for the overall composition: who calls who to do what. IoC helps remove some of the worries about how you resolve and load those dependencies but it does not solve the problem of how you structure the app overall.
Even if you refactor to smaller classes (which I totally am in favor of) someone still has to know to compose all those smaller classes to get work done. So perhaps you use smaller classes with fewer constructor dependencies then you have a few “dirty” classes that know who to call?
From a guy who works with the VS team I thought you’d have this all figured out?
January 21, 2010 - 9:34 am
Shouldn’t your IoC container be able to create a proxy for you to do lazy instantiation, even if it is a constructor injected dependency?
It’s an inconvenience, especially when testing, to pass so many dependencies in, but if you’re worried about all that instantiation affecting performance, would you be better off dealing with it via the container?…maybe even via config of the container where you could tell it these dependencies of the class are always needed and these others are lazy.
January 21, 2010 - 9:46 am
Surely they can and that is something I should dig into because I’m pretty big on letting containers do the work. I guess the counter to that is you probably shouldn’t rely on that behavior 100% of the time because what if it changes.
One thing that Uncle Bob pointed out in his article, is to keep those details out of your app. It is pretty rare that I make container calls directly from my classes and if I do it is through some type of factory abstraction.
The testing inconvenience can be painful, but using something like Moq you can setup just the pieces you need for the test to run.
Good comments, now I’m thinking I should update the post.