Inversion of Control Containers and The Dependency Injection Pattern
Inversion of Control Containers and The Dependency Injection Pattern
1 of 17
http://martinfowler.com/articles/injection.html
23 January 2004
Martin Fowler
Contents
Components and Services
A Naive Example
Inversion of Control
Forms of Dependency Injection
Constructor Injection with PicoContainer
Setter Injection with Spring
Interface Injection
Using a Service Locator
Using a Segregated Interface for the Locator
A Dynamic Service Locator
Using both a locator and injection with Avalon
Deciding which option to use
Service Locator vs Dependency Injection
Constructor versus Setter Injection
Code or configuration files
Separating Configuration from Use
Some further issues
Concluding Thoughts
One of the entertaining things about the enterprise Java world is the huge amount of
activity in building alternatives to the mainstream J2EE technologies, much of it happening
in open source. A lot of this is a reaction to the heavyweight complexity in the mainstream
J2EE world, but much of it is also exploring alternatives and coming up with creative
ideas. A common issue to deal with is how to wire together different elements: how do you
fit together this web controller architecture with that database interface backing when they
were built by different teams with little knowledge of each other. A number of frameworks
have taken a stab at this problem, and several are branching out to provide a general
capability to assemble components from different layers. These are often referred to as
lightweight containers, examples include PicoContainer, and Spring.
Underlying these containers are a number of interesting design principles, things that go
beyond both these specific containers and indeed the Java platform. Here I want to start
exploring some of these principles. The examples I use are in Java, but like most of my
writing the principles are equally applicable to other OO environments, particularly .NET.
29/02/2016 14:37
2 of 17
http://martinfowler.com/articles/injection.html
A Naive Example
To help make all of this more concrete I'll use a running example to talk about all of this.
Like all of my examples it's one of those super-simple examples; small enough to be
unreal, but hopefully enough for you to visualize what's going on without falling into the
bog of a real example.
In this example I'm writing a component that provides a list of movies directed by a
particular director. This stunningly useful function is implemented by a single method.
class MovieLister...
The implementation of this function is naive in the extreme, it asks a finder object (which
we'll get to in a moment) to return every film it knows about. Then it just hunts through this
list to return those directed by a particular director. This particular piece of naivety I'm not
going to fix, since it's just the scaffolding for the real point of this article.
The real point of this article is this finder object, or particularly how we connect the lister
object with a particular finder object. The reason why this is interesting is that I want my
wonderful
method to be completely independent of how all the movies
29/02/2016 14:37
3 of 17
http://martinfowler.com/articles/injection.html
are being stored. So all the method does is refer to a finder, and all that finder does is
know how to respond to the
method. I can bring this out by defining an interface
for the finder.
Now all of this is very well decoupled, but at some point I have to come up with a concrete
class to actually come up with the movies. In this case I put the code for this in the
constructor of my lister class.
class MovieLister...
The name of the implementation class comes from the fact that I'm getting my list from a
colon delimited text file. I'll spare you the details, after all the point is just that there's some
implementation.
Now if I'm using this class for just myself, this is all fine and dandy. But what happens
when my friends are overwhelmed by a desire for this wonderful functionality and would
like a copy of my program? If they also store their movie listings in a colon delimited text
file called "movies1.txt" then everything is wonderful. If they have a different name for their
movies file, then it's easy to put the name of the file in a properties file. But what if they
have a completely different form of storing their movie listing: a SQL database, an XML
file, a web service, or just another format of text file? In this case we need a different class
to grab that data. Now because I've defined a
interface, this won't alter my
method. But I still need to have some way to get an instance of the right
finder implementation into place.
29/02/2016 14:37
4 of 17
http://martinfowler.com/articles/injection.html
Expanding this into a real system, we might have dozens of such services and
components. In each case we can abstract our use of these components by talking to
them through an interface (and using an adapter if the component isn't designed with an
interface in mind). But if we wish to deploy this system in different ways, we need to use
plugins to handle the interaction with these services so we can use different
implementations in different deployments.
So the core problem is how do we assemble these plugins into an application? This is one
of the main problems that this new breed of lightweight containers face, and universally
they all do it using Inversion of Control.
Inversion of Control
When these containers talk about how they are so useful because they implement
"Inversion of Control" I end up very puzzled. Inversion of control is a common
characteristic of frameworks, so saying that these lightweight containers are special
because they use inversion of control is like saying my car is special because it has
wheels.
The question is: "what aspect of control are they inverting?" When I first ran into inversion
of control, it was in the main control of a user interface. Early user interfaces were
controlled by the application program. You would have a sequence of commands like
"Enter name", "enter address"; your program would drive the prompts and pick up a
response to each one. With graphical (or even screen based) UIs the UI framework would
contain this main loop and your program instead provided event handlers for the various
fields on the screen. The main control of the program was inverted, moved away from you
to the framework.
For this new breed of containers the inversion is about how they lookup a plugin
implementation. In my naive example the lister looked up the finder implementation by
directly instantiating it. This stops the finder from being a plugin. The approach that these
containers use is to ensure that any user of a plugin follows some convention that allows a
separate assembler module to inject the implementation into the lister.
As a result I think we need a more specific name for this pattern. Inversion of Control is
too generic a term, and thus people find it confusing. As a result with a lot of discussion
with various IoC advocates we settled on the name Dependency Injection.
I'm going to start by talking about the various forms of dependency injection, but I'll point
out now that that's not the only way of removing the dependency from the application
class to the plugin implementation. The other pattern you can use to do this is Service
Locator, and I'll discuss that after I'm done with explaining Dependency Injection.
29/02/2016 14:37
5 of 17
http://martinfowler.com/articles/injection.html
There are three main styles of dependency injection. The names I'm using for them are
Constructor Injection, Setter Injection, and Interface Injection. If you read about this stuff in
the current discussions about Inversion of Control you'll hear these referred to as type 1
IoC (interface injection), type 2 IoC (setter injection) and type 3 IoC (constructor injection).
I find numeric names rather hard to remember, which is why I've used the names I have
here.
The finder itself will also be managed by the pico container, and as such will have the
filename of the text file injected into it by the container.
class ColonMovieFinder...
The pico container then needs to be told which implementation class to associate with
each interface, and which string to inject into the finder.
29/02/2016 14:37
6 of 17
http://martinfowler.com/articles/injection.html
This configuration code is typically set up in a different class. For our example, each friend
who uses my lister might write the appropriate configuration code in some setup class of
their own. Of course it's common to hold this kind of configuration information in separate
config files. You can write a class to read a config file and set up the container
appropriately. Although PicoContainer doesn't contain this functionality itself, there is a
closely related project called NanoContainer that provides the appropriate wrappers to
allow you to have XML configuration files. Such a nano container will parse the XML and
then configure an underlying pico container. The philosophy of the project is to separate
the config file format from the underlying mechanism.
To use the container you write code something like this.
Although in this example I've used constructor injection, PicoContainer also supports
setter injection, although its developers do prefer constructor injection.
The third step is to set up the configuration for the files. Spring supports configuration
through XML files and also through code, but XML is the expected way to do it.
29/02/2016 14:37
7 of 17
http://martinfowler.com/articles/injection.html
Interface Injection
The third injection technique is to define and use interfaces for the injection. Avalon is an
example of a framework that uses this technique in places. I'll talk a bit more about that
later, but in this case I'm going to use it with some simple sample code.
With this technique I begin by defining an interface that I'll use to perform the injection
through. Here's the interface for injecting a movie finder into an object.
This interface would be defined by whoever provides the MovieFinder interface. It needs
to be implemented by any class that wants to use a finder, such as the lister.
class MovieLister implements InjectFinder
I use a similar approach to inject the filename into the finder implementation.
Then, as usual, I need some configuration code to wire up the implementations. For
simplicity's sake I'll do it in code.
class Tester...
29/02/2016 14:37
8 of 17
http://martinfowler.com/articles/injection.html
This configuration has two stages, registering components through lookup keys is pretty
similar to the other examples.
class Tester...
A new step is to register the injectors that will inject the dependent components. Each
injection interface needs some code to inject the dependent object. Here I do this by
registering injector objects with the container. Each injector object implements the injector
interface.
class Tester...
When the dependent is a class written for this container, it makes sense for the
component to implement the injector interface itself, as I do here with the movie finder. For
generic classes, such as the string, I use an inner class within the configuration code.
class ColonMovieFinder implements Injector...
class Tester...
The container uses the declared injection interfaces to figure out the dependencies and
the injectors to inject the correct dependents. (The specific container implementation I did
here isn't important to the technique, and I won't show it because you'd only laugh.)
29/02/2016 14:37
9 of 17
http://martinfowler.com/articles/injection.html
In this case I'll use the ServiceLocator as a singleton Registry. The lister can then use that
to get the finder when it's instantiated.
class MovieLister...
class ServiceLocator...
As with the injection approach, we have to configure the service locator. Here I'm doing it
in code, but it's not hard to use a mechanism that would read the appropriate data from a
configuration file.
class Tester...
class ServiceLocator...
29/02/2016 14:37
10 of 17
http://martinfowler.com/articles/injection.html
I've often heard the complaint that these kinds of service locators are a bad thing because
they aren't testable because you can't substitute implementations for them. Certainly you
can design them badly to get into this kind of trouble, but you don't have to. In this case
the service locator instance is just a simple data holder. I can easily create the locator with
test implementations of my services.
For a more sophisticated locator I can subclass service locator and pass that subclass into
the registry's class variable. I can change the static methods to call a method on the
instance rather than accessing instance variables directly. I can provide threadspecific
locators by using threadspecific storage. All of this can be done without changing clients
of service locator.
A way to think of this is that service locator is a registry not a singleton. A singleton
provides a simple way of implementing a registry, but that implementation decision is
easily changed.
The locator then needs to implement this interface to provide access to a finder.
29/02/2016 14:37
11 of 17
http://martinfowler.com/articles/injection.html
You'll notice that since we want to use an interface, we can't just access the services
through static methods any more. We have to use the class to get a locator instance and
then use that to get what we need.
On the whole I dislike this approach. Although it's certainly flexible, it's not very explicit.
The only way I can find out how to reach a service is through textual keys. I prefer explicit
methods because it's easier to find where they are by looking at the interface definitions.
29/02/2016 14:37
12 of 17
http://martinfowler.com/articles/injection.html
The service method is an example of interface injection, allowing the container to inject a
service manager into MyMovieLister. The service manager is an example of a service
locator. In this example the lister doesn't store the manager in a field, instead it
immediately uses it to lookup the finder, which it does store.
29/02/2016 14:37
13 of 17
http://martinfowler.com/articles/injection.html
29/02/2016 14:37
14 of 17
http://martinfowler.com/articles/injection.html
give you a clear statement of what it means to create a valid object in an obvious place. If
there's more than one way to do it, create multiple constructors that show the different
combinations.
Another advantage with constructor initialization is that it allows you to clearly hide any
fields that are immutable by simply not providing a setter. I think this is important - if
something shouldn't change then the lack of a setter communicates this very well. If you
use setters for initialization, then this can become a pain. (Indeed in these situations I
prefer to avoid the usual setting convention, I'd prefer a method like
, to stress that
it's something you should only do at birth.)
But with any situation there are exceptions. If you have a lot of constructor parameters
things can look messy, particularly in languages without keyword parameters. It's true that
a long constructor is often a sign of an over-busy object that should be split, but there are
cases when that's what you need.
If you have multiple ways to construct a valid object, it can be hard to show this through
constructors, since constructors can only vary on the number and type of parameters. This
is when Factory Methods come into play, these can use a combination of private
constructors and setters to implement their work. The problem with classic Factory
Methods for components assembly is that they are usually seen as static methods, and
you can't have those on interfaces. You can make a factory class, but then that just
becomes another service instance. A factory service is often a good tactic, but you still
have to instantiate the factory using one of the techniques here.
Constructors also suffer if you have simple parameters such as strings. With setter
injection you can give each setter a name to indicate what the string is supposed to do.
With constructors you are just relying on the position, which is harder to follow.
If you have multiple constructors and inheritance, then things can get particularly
awkward. In order to initialize everything you have to provide constructors to forward to
each superclass constructor, while also adding you own arguments. This can lead to an
even bigger explosion of constructors.
Despite the disadvantages my preference is to start with constructor injection, but be
ready to switch to setter injection as soon as the problems I've outlined above start to
become a problem.
This issue has led to a lot of debate between the various teams who provide dependency
injectors as part of their frameworks. However it seems that most people who build these
frameworks have realized that it's important to support both mechanisms, even if there's a
preference for one of them.
29/02/2016 14:37
15 of 17
http://martinfowler.com/articles/injection.html
A contrasting case is where the assembly is quite complex, involving conditional steps.
Once you start getting close to programming language then XML starts breaking down
and it's better to use a real language that has all the syntax to write a clear program. You
then write a builder class that does the assembly. If you have distinct builder scenarios
you can provide several builder classes and use a simple configuration file to select
between them.
I often think that people are over-eager to define configuration files. Often a programming
language makes a straightforward and powerful configuration mechanism. Modern
languages can easily compile small assemblers that can be used to assemble plugins for
larger systems. If compilation is a pain, then there are scripting languages that can work
well also.
It's often said that configuration files shouldn't use a programing language because they
need to be edited by non-programmers. But how often is this the case? Do people really
expect non-programmers to alter the transaction isolation levels of a complex server-side
application? Non-language configuration files work well only to the extent they are simple.
If they become complex then it's time to think about using a proper programming
language.
One thing we're seeing in the Java world at the moment is a cacophony of configuration
files, where every component has its own configuration files which are different to
everyone else's. If you use a dozen of these components, you can easily end up with a
dozen configuration files to keep in sync.
My advice here is to always provide a way to do all configuration easily with a
programmatic interface, and then treat a separate configuration file as an optional feature.
You can easily build configuration file handling to use the programmatic interface. If you
are writing a component you then leave it up to your user whether to use the
programmatic interface, your configuration file format, or to write their own custom
configuration file format and tie it into the programmatic interface
29/02/2016 14:37
16 of 17
http://martinfowler.com/articles/injection.html
Concluding Thoughts
The current rush of lightweight containers all have a common underlying pattern to how
they do service assembly - the dependency injector pattern. Dependency Injection is a
useful alternative to Service Locator. When building application classes the two are
roughly equivalent, but I think Service Locator has a slight edge due to its more
straightforward behavior. However if you are building classes to be used in multiple
applications then Dependency Injection is a better choice.
If you use Dependency Injection there are a number of styles to choose between. I would
suggest you follow constructor injection unless you run into one of the specific problems
with that approach, in which case switch to setter injection. If you are choosing to build or
obtain a container, look for one that supports both constructor and setter injection.
The choice between Service Locator and Dependency Injection is less important than the
principle of separating service configuration from the use of services within an application.
Share:
design
application architecture
29/02/2016 14:37
17 of 17
http://martinfowler.com/articles/injection.html
Acknowledgments
My sincere thanks to the many people who've helped me with this article. Rod Johnson, Paul Hammant, Joe
Walnes, Aslak Hellesy, Jon Tirsn and Bill Caputo helped me get to grips with these concepts and commented
on the early drafts of this article. Berin Loritsch and Hamilton Verissimo de Oliveira provided some very helpful
advice on how Avalon fits in. Dave W Smith persisted in asking questions about my initial interface injection
configuration code and thus made me confront the fact that it was stupid. Gerry Lowry sent me lots of typo fixes enough to cross the thanks threshold.
Significant Revisions
23 January 2004: Redid the configuration code of the interface injection example.
16 January 2004: Added a short example of both locator and injection with Avalon.
14 January 2004: First Publication
29/02/2016 14:37