Skip to content.

Manageability

Sections
Personal tools
You are here: Home » blog » stuff » Deconstructing Dependency Injection

Deconstructing Dependency Injection

Document Actions

Rickard Oberg focuses his microscope on the intricacies of Dependency Injection. He shows how the apparently simple use of the "new" keyword can lead to many assumptions that we may not noticed. He then explains the difference with a dependecy injection example:

public class Foo { Bar bar; public Foo(Bar aBar) { bar = aBar; } ... }
  1. Bar can be a class, an abstract class, or an interface
  2. Foo does not need to know how Bar is instantiated
  3. The Bar instance can be used by other components
  4. Bar can have any configuration needs
  5. The user of Foo needs to know how to provide a Bar

A while back ago, Jonathan Amsterdam wrote a article on DDJ explainied why "new was considered harmful". Amsterdam proposed the use of several creation patterns and concludes:

There is a difference between requesting an object and creating one. The first is an abstraction; it should be designed into a class and should be under the class's control. The second is a low-level implementation detail.

In other words coupling the mechanism of allocating an object with one of requesting an object can lead to overly rigid and inflexible designs. Dependency Injection takes this decoupling one indirection further by separating configuration from the context of which it is used.

Howard Ship digs even in deeper with this connection will object allocation, when he contrasts Dependency Injection with Garbage Collection. In his entry "Dependency Injection -- the mirror of Garbage Collection" he writes:

Garbage collection is the last stage of an object's life cycle, but there's just as much going on at the start of the object's life cycle. That's why component frameworks and dependency injection containers (such as HiveMind, Spring, Picocontainer and Avalon) are so important.
You're willing to let something else manage the death of your objects because it, the Garbage Collector, can do a better job than you can. Likewise, you should accept that a container, whose only responsibility is to construct and configure your objects, will do a better job of it than your own code. Embrace that fact ... and get back to interesting work!

When you take this viewpoint of looking at the services that can support an object's lifetime then you quickly realize that decoupling configuration has always been a practice employed by component models. The Java Beans component model is patterned after the earlier Delphi component model (i.e. properties and events). In Delphi, configuration was stored in a resource file and to be used when a new component was instantiated. Unfortunately, this practice was abandoned by early Java IDE implementations. Java IDEs incorrectly embedded configuration in code.

Components are actually runtime configurable entities. Our class-based bias blinds us to the fact that configuration can be a runtime activity and therefore part of an object's lifecycle. So in the beginning of a component's lifetime you have "allocation", "configuration" and then "discovery".

It only makes perfect sense that standard infrastructure is provided to support these phases. However, the obstacle that needs to be avoided is the fact that these phases should be decoupled. The main weakness of earlier frameworks is primarilly this oversight. Allocation, configuration and discovery are disjoint steps and are most naturally decoupled.


Last modified 2005-02-18 12:04 PM

visitors
reading
 
 

Powered by Plone

This site conforms to the following standards: