Alright, I’m just back from vacation (report will be posted soon) and I have
been following the reactions to my classification of getter injections with a
lot of interest. Just for memory, here it is again:
- Force the dependency to be passed to the constructor (not always
possible and very invasive).
- Have the container invoke a setter, or set a field on your class (mildly
intrusive since it forces you to specify a setter or a field you will never
- Have the container provide the getter (not intrusive at all, except that
now, you need the container for your application, which makes
out-of-container testing problematic).
It looked like we had reached a stalemate: option 3 looks like the best
of both worlds except that it mandates the presence of the container, which is
bad news for testability and brings us back to square one.
And then, Bob Lee came up to me and said "Why does the getter need to be
abstract again?". And he proceeded to put together a
quick proof of concept, which
discussed on TheServerSide since then.
It was one of these "doh!" moments. Of course, the getter doesn’t need
to be abstract, but I guess my EJB bias made me overlook this fact. Bob is
right, there is absolutely no need for this getter to be abstract, and now we
have an answer for all these Test-Driven Development weeni^H^H^H^H^H (sorry, had
a Hani moment) advocates: not only does getter injection work well with
TDD, it makes TDD a first class citizen.
In the absence of a container, your class is testable right out of the box.
All you need to do is provide a default implementation for your getter that will
work in your testing environment. And if you run your code in a container,
the getter will be overridden with a different value for production or staging.
How is that for the best of both worlds?