Sunday, January 20, 2013

Dependency Injection Part I: A Basic Introduction

There has been much debate around Dependency Injection (DI). In this series I will explore dependency injection: what it is, the arguments for and against it, when to use (or not use) it, and some code samples.

First of all: What is Dependency Injection? You can read the Wikipedia article on it as well as I can, but to put it in plain english: Instead of a class instantiating its own member instances (dependencies), the dependencies are given to it. This is easiest to see with a little sample code.

// without DI
public class Parent {
  Something s = new ConcreteSomething();
}

// with DI
public class Parent {
  private Something s

  // constructor injection
  public Parent(Something t) {
     s = t;
  }

  // setter injection
  public void setSomething(Something t) {
     s = t;
  }
}

Note the two different ways of getting Something into Parent: via a constructor or setter. There are other ways to accomplish this (Martin Fowler's DI Post includes Interface Injection) but these are the techniques that I have seen used the most often. I favor constructor injection in particular because I like having the object constructed in a usable state, and think it’s good practice to make dependencies explicit. That way if the constructor argument list gets too long, it’s a good clue that your class might be trying to do too much!

Next, there is a difference between DI and an DI Container, and many people confuse the two. DI is just the design pattern, the idea of arranging classes in such a way that a dependency is given to a using class instead of the using class instantiating it. A DI container, on the other hand, is a framework that facilitates DI to the point where you can construct an entire application using dependency injection. When people argue for or against DI, they sometimes are actually arguing for or against the idea of using a DI container vs the design pattern of DI itself (or vice versa). For purposes of this blog, I will use DI to mean using a DI container to structure an entire application. Arguments revolving around this should be a superset of arguments revolving around DI as a design pattern.

Finally, some things to note about how to use DI in Java: The javax.inject package (aka, CDI or “Context and Dependency Injection) is a standard in Java EE 6, so it’s not hard to get started with using this in your own code. The related JSR’s JSR-330 and JSR-299 (which are different from each other) have various implementations available, such as Dependency Shot, Spring, and Pico. Guice 3.0 is the Reference Implementation for JSR-330. Later we will be looking at working samples using Spring and Guice.

In the next post, we’ll examine the arguments revolving around DI, and get a feel for when it is appropriate.

No comments:

Post a Comment