Pure Danger Tech


navigation
home

Using patterns to change dependency injection styles

30 Jul 2007

The two most common forms of dependency injection are constructor injection and setter injection. They’ve got pros and cons of course, and both have their place. Setter injection is simple, allows you choose which parts of the object to inject, can make setting up bidirectional relationships easier, but has the downside that it’s easier to create an object in a partially constructed state. Constructor injection allows more control over the instantiation of a valid object but can lead to a bunch of constructors and/or the use of lots of optional arguments.

But this post is really more about how you can use the Builder and Factory Method patterns to effectively choose between setter injection and constructor injection.

For instance, consider an object defined with constructor injection: [source:java]

public class Foo {

private A;

private B;

private C;

public Foo(A a, B b, C c) {

this.a = a;

this.b = b;

this.c = c;

}

}

[/source]

But say that b and c are optional (and perhaps we also have d, e, and f). So instead, we create a Builder object: [source:java]

public class FooBuilder {

private A a;

private B b;

private C c;

public void setA(A a) { this.a = a; }

public void setB(B b) { this.b = b; }

public void setC(C c) { this.c = c; }

public Foo build() { return new Foo(a, b, c); }

}

[/source]

So, if you look at the use of FooBuilder vs the use of Foo, you’ll see that we have effectively turned constructor injection into setter injection.

Similarly, given a class that uses setter injection, you can turn that into constructor injection style by using one or more Factory methods that correspond to the constructors in constructor injection: [source:java]

public class Foo {

private A a;

private B b;

private C c;

public void setA(A a) { this.a = a; }

public void setB(B b) { this.b = b; }

public void setC(C c) { this.c = c; }

public Foo() { }

}</p>

public class FooFactory {

public Foo newFoo(A a, C c) {

Foo foo = new Foo();

foo.setA(a);

foo.setC(c);

return foo;

}

}

[/source]

Just a thought….