IoC containers, Part 1
Mike Spille wrote an
interesting essay about Inversion of Control containers, (with a
followup
here). He gives a checklist of desirable features in these
containers, and surveys HiveMind, Spring, and PicoContainer. PicoContainer
comes out worst, partly because it lacks some of the features from his
checklist (and in fact, these omissions are deliberate on the part of
the creators of PicoContainer).
I have a particular interest in IoC containers, because I developed
one at work, and continue to maintain it and enhance it today. I call
it the init framework (colleagues often call it
components.xml, because its per-module configuration files
have that name). Here, I'll just call it TIF.
In terms of generalities, TIF has a lot in common with the well-known
IoC containers. It shares many ideas and some specific techniques,
and the basic benefits are similar. But these similarities represent
a case of convergent evolution. I began work on TIF a little over 2
years ago (the CVS logs say the first check-in was on 2002-07-01; the
first lines of code must have been written a few days earlier). If
those other IoC containers existed at that time, I wasn't aware of
them.
(From the public CVS repositories, it seems that HiveMind originates
in May 2003, PicoContainer from mid-2003, and Spring from August 2003,
but it is possible that those dates are misleading: the projects may
have been hosted elsewhere before moving to their current
repositories. In any case, some of these ideas may well have been
around earlier; I seem to remember being aware of Apache Avalon, though it was
certainly not something I had any desire to imitate.)
So I find it interesting to compare TIF with the open source ones, and
to consider why I made the design choices I did and why the authers of
the other containers made similar or different choices. Since Mike's
essay it perhaps the nearest thing I have seen to a survey of the IoC
"market", it provides useful context for these comparisons.
In summary, here is how the comparison comes out:
- Like HiveMind, TIF has a strong emphasis on XML-based configuration.
- Like HiveMind and Spring, TIF has strong support for resolving
dependencies both by name and by type.
- Like PicoContainer, TIF supports only constructor-based injection,
not setter-based injection. However, there is a twist, which I
believe achieves many of the benefits of setter-based injection
without raising the difficult questions of that approach.
- Like PicoContainer, TIF des not support cyclic dependencies. It
did support them at one point, but that support was removed, and I
have no inclination to put it back.
These last two points stand out, because Mike's article, and the
subsequent discussion, criticized PicoContainer for missing precisely
these features. Mike's position is that these are examples where the
creators of PicoContainer put their purist principles ahead of the
pragmatic needs of developers who might use their container. I can't
speak for the creators of PicoContainer, but my decisions had very
pragmatic reasons behind them: If my container doesn't meet the needs
of the real-world projects I work on, my colleagues simply won't use
it!
In subsequent posts, I will consider each of these features in turn,
and explain how TIF works the way it does. Then I will write another
post to describe notable features of TIF not shared by other
containers.
(These posts are partly a response to colleagues who have asked me why
I wrote TIF when there are similar open-souce projects around, and why
it doesn't support cyclical dependencies. I expect someone will
eventually ask me why it doesn't support setter-based injection, and
I will be able to point them here.)