We're reaching the end of 2019 and we just started our migration from Dagger 1 to Dagger 2.

…

That's right, we're still using Dagger 1. That may sound surprising to you, especially if you're lucky enough to be working on a younger codebase. That's not the case for a lot of (most?) people, though, including us at Blinkist — and that's why talking about legacy technologies migration is still relevant most of the time.

If there's one thing we learned from our experience migrating from Cupboard to Room is that migrating the whole thing at once is painful. So even though finding a step by step strategy might seem tricky at first, it'll most likely be worth it. So how do we migrate step by step from Dagger 1 to Dagger 2?

Baby steps

The way for a gradual migration is to slowly migrate piece by piece of the codebase without breaking the code that hasn't been migrated yet. The only way to do that is if we can have Dagger 1 and Dagger 2 as dependencies at the same time working together. And even though that may seem a very unlikely scenario, that's actually possible to achieve.

There's a great blogpost by Fernando Cejas from a couple of years ago on this:

It suggests the idea of using the Gradle Shadow Plugin (which is basically the Gradle version of the Maven Shade Plugin) to relocate Dagger 2 packages so they can be referenced by other names, avoiding clashes with Dagger 1 annotations.

What this means is that after the setup is done, we can write things like these, for instance:

This enables the step by step migration we want. We can now easily choose whether a class should be in both graphs, and we can easily migrate it from one graph to the other. We can mirror a whole Dagger 1 module to Dagger 2 by just applying some annotations, and we can also choose to bring only a few specific @Provides methods if we want.

The migration process becomes safer because we can choose until where we want to go and how much we want to affect by simply adding or removing annotations in the right places. Sometimes it really feels like we're performing a surgery in our object graph creature, limb by limb.

One annoyance about this strategy is how to setup the Dagger 2 dependency to make this work — and that's actually the main reason I decided to write this blogpost. Having to build the setup yourself is an unpleasant chore, so we created a repository to help with that:

Now all you have to do to start working with a shaded version of Dagger 2 is add this in your build:

It currently only supports the latest version of Dagger 2. If you want a different version, you can fork the repository, change the dagger.version property in the parent POM file, and use JitPack on your own repo. And when a newer Dagger version comes out, PRs are more than welcome!

Assisted Injection

If you want to be able to take advantage of AssistedInject (I wrote a bit about it here) during the migration (like we do) then there's more work needed. Unfortunately, the shade plugin trick won't work here since there's some hardcoded references on AssistedInject. So the only solution is to fork it and update those references.

Behold our fork:

If you want AssistedInject alongside Dagger 2 Shaded, you just need this in your build: