Coding: Invariant checking on dependency injected components
I've written a couple of times previously about invariant checking in constructors and I had an interesting discussion with some colleagues recently around doing this type of defensive programming when the object in question has its dependencies injected by a container.
Quite often we would see code similar to this in a controller:
public class SomeController { public SomeController(Dependency1 valueOne, Dependency2 valueTwo) { AssertThat.isNotNull(valueOne); AssertThat.isNotNull(valueTwo); // and so on } }
Where 'SomeController' would have 'Dependency1′ and 'Dependency2′ set up in a Spring configuration file in this example.
I can't really see much benefit in this type of pre condition checking although Raph pointed out that if we got the configuration for this bean wrong then having these assertions would allow us to get quicker feedback.
While that is true it seems to me that we would maybe achieve quicker feedback by a few seconds in return for the clutter that we end up creating in our code. We have to read those assertions every time we come to this class.
I would prefer to have some specific tests for the dependency injection container if we're interested in getting quick feedback in that area.
That seems to be a cleaner solution than having these types of checks in production code or am I missing something?
I'd say that that's a failure of the IoC container. Most IoC tools would throw an exception if it didn't know how to resolve a constructor dependency and fail quickly.
Human beings should not be wasted on repetitive defensive programming checks like the Asserts above.
Jeremy D. Miller
31 Oct 09 at 6:28 am
[...] Coding: Invariant checking on dependency injected components – Mark Needham continues discussing invariant checking, this time looking at checking on the dependencies that should be being provided by the Dependency Injection framework, asking if this is necessary, and if there is a better place to check these dependencies [...]
Reflective Perspective - Chris Alcock » The Morning Brew #467
2 Nov 09 at 6:30 pm
+1 with Jeremy on this…
Awkward Coder
2 Nov 09 at 8:33 pm
The people behind the Google testing blog wrote/said something to the effect of, "it is much better to have that code execute in a test harness"
For example, now you have limited yourself from passing null values in a unit test.
For instance if youre writing a test to cover Dependency1, you shouldn't HAVE to mock out Dependency2, you should be able to just pass null to signify that no code executes, as a part of this test, that uses that instance of Dependency2 (because you would get a null pointer exception when you ran the test).
So not only is it a violation of DRY it limits your design, makes your tests harder to understand at a glance.
Josh Ribakoff
2 Nov 09 at 11:34 pm
I also agree that if the IoC container provides a null value, it is a failure of the container. However, simply because we "know" an IoC container will exist doesn't mean we code for it. The benefit to an IoC container is that your classes shouldn't "know" it's there. In other words, by assuming that an IoC container will inject our dependencies for us is like creating a dependency upon that IoC container that isn't present anywhere in the class. I would say that this is worse than just newing up the dependency inside.
So, in summary. Do the invariant checking! Sure, it's probably not necessary, but at least things are explicit.
Craig Wilson
2 Nov 09 at 11:36 pm
I'd say don't put the checks there.
1) If you're using an IOC, such as Spring, there is an XML attribute (dependency-check) to check that either all dependencies are injected, primitives, or objects.
2) If you're not using an IOC, then you're going to have one class or part of the application that is wiring everything up, such as the class that contains main(). It would be very easy _not_ to make the mistake of passing in null, and on the rare chance that someone did, it's easy to spot.
Kenrick Chien
5 Nov 09 at 10:51 pm