Articles
Dagger + Anvil: Learning to Love Dependency Injection on Android

The Android ecosystem has a healthy array of options for dependency injection. These days, the most common choices are Dagger (alone, with Hilt, or with Anvil), Koin, Kodein, and doing it by hand. Each option has its own set of pros and cons. At Tonal, we use Dagger with Anvil and it has been working so well that we think that it would be valuable to share our learnings with the Android community.
What is Anvil?
Historically, dependency injection frameworks tradeoff complexity and boilerplate for powerful features and type safety. When used alone, Dagger can be complex to set up, learn, and maintain. However, Anvil makes Dagger more powerful yet easier to use and teach to your team.
- Simple: nearly all of the complexity, learning, and maintenance overhead for the vast majority of day-to-day tasks nearly disappears.
- Modularization and dev apps: Anvil has become instrumental in building a highly modularized codebase and enabling dev apps that compile only a subset of our code.
- Build time: build times went down due to Anvil’s compiler plugin replacing Dagger’s kapt plugin. Anvil has more info on its README.
- Custom plugins: plugins can be written to remove boilerplate in ways that are specific to our codebase.
- No gotchas: we never hit any walls or gotchas because Anvil’s functionality is a complete superset of Dagger.
These benefits of Anvil come with all of the things that make Dagger great:
- Compile-time safety: you will never get a runtime crash due to a missing dependency.
- Powerful: Dagger is full of functionality such as multibinding that you can learn and incorporate over time as you need.
- Community: Dagger has a large and active community.
Simple Use Case
Let’s write some code that fetches the user’s current location and then fetches the weather.
So far, this looks the same as Dagger. Notice that you don’t need to declare your dependencies in modules. You can @Inject
your constructors directly with Dagger or any of its derivatives. In this example, @Singleton
is also used to indicate that the same instance of LocationProvider
should be provided to all other dependencies that inject it.
Full Article: Gabriel Peal @ Medium
