Refactor Your Way to a Dependency Injection Container

December 7, 2011 (updated July 6, 2015) Dependency Inversion Principle (DIP)


This is a companion discussion topic for the original entry at http://blog.thecodewhisperer.com/permalink/refactor-your-way-to-a-dependency-injection-container

Clear, short, to the point.

I've often spoken about this as separating configuration logic from "runtime" logic. Where configuration is which concrete objects are used in the application and runtime is the rest. There might be a better word than runtime since indeed the EntryPoint.initialize() is also runtime, suggestions are welcome :)

You don't mention that this will lead to a dependency injection tool used well. In every application I've come by the dependency injection framework was solely used to implement the service locator pattern. It's like we (me including) don't see the good principles because of the frameworks built on them.

Yes: I didn't realise that many people use a dependency injection container as a service registry, but it immediately makes sense to me that that would happen. A dependency injection container can do more than act as a service registry: it wants to make locating services transparent to every part of your application except the entry point. Let it!

fair enough

but as far as dependency injection is the hot and spicy flavour of inversion of control, some containers implement also the sweet and sour dependency lookup

The way I understand those terms, dependency lookup does not (on its own) invert any control. Service Locator, to be specific, is not a kind of Inversion of Control at all. Service Locator misses the point entirely of Inversion of Control, although it does at least remove some duplication.

I've had some problems with pushing everything into one 'configuration' class that just calls `new` to assemble the runtime of the project. Namely, that class gets large and hard to understand (maybe I make too many small objects?).

I've ended up breaking up that class into a small 'dsl' like layer that uses jmock-style (this was in JavaScript though) high level language to describe each separate subsystem, then the entry point calls upon those to create each subsystem, then wires the subsystems together as they need it.

It sounds like your JMock-like DSL removes some duplication related to the cascading `new`s. I would certainly do that, if I didn't externalise everything to a file. I like how Spring tried to do this, before people decided they wanted to program in XML.

to me, ioc means that container manages object lifecycle, but you might put the ioc label wherever you want ;)

dl menas that container calls services/repo/* when a lookup context is available &. objects should implement container-specific api... yes, its painful and awkward

i do agree with your pov but i can't see why you don't like external config :P

nice post

Looking up a dependency, then using it does not invert any control, so how can you call that inversion of control? Inverting control involves letting the framework invoke your logic.

I can't see why you think I don't like external configuration. I don't always do it right away, and I think Dependency Inversion works quite well without it, but I don't *dislike* it.

a servlet container + jndi is an ioc container as well

it manages creation, init and destroy (object lifecycle) as well as the calls to doGet/doPost/service
it provides a way to wire the *components* it manages thru the service registry (jndi)

like it or not ;)

spring implements the same thing: it manages object lifecycle and wires the components (annotations, xml)

Servlet container, yes; JNDI, no. JNDI does not invert any control; it's a component registry.

Answer me this: what control exactly does a JNDI directory invert?

the servlet container does not provide a way to locate the objects managed by the container so it's incomplete

the example ioc container should be [servlet container + jndi] together

A servlet container inverts control by managing the lifecycle of the servlet. Inversion of Control does not mean that you have access to the servlet management system. In fact, Inversion of Control means that you don't *need* access to the servlet management system. You don't *want* to depend on the servlet management system directly: that would create a cyclic dependency.

In your example of servlet container together with a JNDI directory, only the servlet container inverts control, and the JNDI directory is an implementation detail of how the servlet container could find components. Nothing about the JNDI directory inverts control. If the servlet container hides the JNDI directory from the rest of the system, then at least the programmer can't create a cyclic dependency.

Inversion of Control does not include component lookup. In fact, Inversion of Control has the goal of taking component lookup out of your hands, letting you simply declare the components you need as parameters. If you look up components yourself, you break the inversion.

nice then!

imo, dependency lookup implies that the managed objects are responsible for doing their own lookups so your code (at least a helper) implements framework related apis

I can't see a cycle here since components just access the registry, not the container itself

think about the ejb world (now changed :) ) it was pure dl

so yes, di is a much more complete implementation strategy of ioc than dl, also cleaner and smarter

short version:
* ioc container manages object lifecycle
* dl: objects are responsible for doing their own lookups
* di: the container wires the components