ad-hockery: /ad·hok'@r·ee/, n.
Gratuitous assumptions... which lead to the appearance of semi-intelligent behavior but are in fact entirely arbitrary. Jargon File

Is this a Dagger I see before me?

Recently Marcin Erdmann and I decided to experiment with using Dagger for dependency injection in a project at work. It’s a super-lightweight DI framework built by Square.

We felt the code we were working on was in danger of getting out of hand. In particular we found ourselves passing a lot of parameters through methods or classes as they were dependencies of objects being used or created deeper in the stack. Testability was suffering as objects and methods were becoming tightly coupled and we were ending up using excessive numbers of mocks & test doubles.

A pet hate of mine is having lots of noise in tests. It makes test maintenance really difficult later when it’s hard to remember which bits of setup are really relevant to the scenario under test.

We felt that dependency injection would be a big help. Unfortunately we’re working on, of all things, an applet. Yeah, I know, 1995 called and wants its web technology back. Suffice to say we have our reasons. The technology may be a little old skool but it’s an interesting scenario in that size is a constraint. We can’t afford to integrate a large library or a big dependency graph. Spring is right out & even the comparatively lightweight Guice is a 544K jar.

We’d both recently seen tweets about Dagger and decided to take a look. As I understand it Dagger targets Android development so similar size concerns apply. Although it’s pre 1.0 right now we quickly found that Dagger is pretty capable. We were able to add annotations to our classes to define dependencies, create a class annotated with @Module to provide those dependencies that needed special handling and inject Provider instances into classes that need to construct new instances of objects that have their own dependencies.

We soon got to the point where we started to see things coming together as we were simplifying objects, removing coupling and deleting noise from tests.

Some Dagger features I really liked:

  • There’s no XML or incomprehensible stringly-typed DSLs to deal with.

  • Tests aren’t dependent on Dagger and unit-level tests can usually ignore it completely.

  • When you do want to use Dagger in a test it’s easy to extend the Module with test doubles standing in for some objects.

  • Unsatisfied dependencies & other problems are reported at compile time.

  • It’s only necessary to define things in the Module when they can’t be constructed automatically by Dagger or need to be specific object instances (such as the applet itself in our scenario).

  • Injecting Provider<V> where V is some kind of domain object that has dependencies of its own means the class using the Provider doesn’t need to know anything about the dependencies of V in order to construct new instances.

Best of all Dagger is only 81K and has a single dependency on the javax.inject framework (adding another 2.4K).

Web Statistics