Anvil Plugin for Dagger in Android

KUNAL PASRICHA
4 min readMay 10, 2022

What is Anvil?

Anvil is a Kotlin compiler plugin (not a DI Framework) to make dependency injection with Dagger easier, yes you read it right “with dagger”, Anvil makes the life of a developer easier by automatically merging the dagger module and component interfaces, which means that the developer doesn’t have to worry about adding the dagger module to all the required dagger components.

No Java support: Anvil is a Kotlin compiler plugin, thus Java isn’t supported. You can use Anvil in modules with mixed Java and Kotlin code for Kotlin classes.

What is Dagger?

Dagger is a Dependency injection(DI) framework, which helps the developers to reduce the boilerplate code, make the code clean and re-usable, and help to enable loose coupling.

Dagger components create a map of the dependencies in the android project so that it can use it to find out where it should get those dependencies when they are needed. To make Dagger do this, you need to create an interface and annotate it with @Component.

Why Square introduce Anvil? — (the problem)

With Dagger one of the major challenges is that your Dagger Component has to be aware of everything that it needs to collect.

For example, whenever you create a new dependency(class), you have to declare it in a module and then that Module must be added to a list in AppComponent in the application module, then you have to go to all other AppComponents in the other application modules, determine whether that application module depends on your feature and add it to that list as well. This can be time-consuming and susceptible task.

And that’s where the Anvil comes to the rescue.

@ContributesTo can be added to Dagger modules and component interfaces that should be included in the Dagger component. Classes with this annotation are automatically merged by the compiler plugin as long as they are on the compile classpath.

@MergeComponent is used instead of the Dagger annotation @Component. Anvil will generate the Dagger annotation and automatically include all modules and component interfaces that were contributed the same scope.

With Anvil you can simply annotate your new dependency with @ContributeTo(AppScope::class) and your AppComponent will automatically inherit all contributed dependencies without explicitly specifying them at the AppComponent level.

without adding the “TimeUtilsModule” to your “AppComponent”, you can inject the TimeUtils class into your app entry points.
after adding a new dependency to the application module using Anvil, the Appcomponent of that application module will remain the same.

The new generated DaggerAppComponent.java will look something like this.

DaggerAppComponent.java(Generated)

Anvil Scopes

Scope classes are only makers.

Because of these scope classes Anvil is able to make a connection between the Dagger component and the Dagger modules and other component interfaces to include. Scope classes are independent of the Dagger scopes. It’s still necessary to set a scope for the Dagger component.

Contributed bindings

@ContributesBinding annotation generates a Dagger binding method for an annotated class and contributes this binding method to the given scope. Lets take this example:

This is a lot of boilerplate, if you always want to use TimeUtils you can simply replace this entire Dagger module with the @ContributesBinding annotation. The equivalent would look like:

Does anvil improves your app performance?

Anvil is a helping tool. Similar to Dagger it doesn’t improve build speed compared to writing all code manually before running a build. The savings are in setup/developer time.

Hilt vs Anvil (which one to choose? 🤔)

Hilt is a Google’s opinionated DI framework for Android. It provides similar features as Anvil. If you are already using hilt, then there is no need to use Anvil. — https://github.com/square/anvil#hilt

If you are familiar with hilt, you must have observed that Anvil is being used to make your existing Dagger DI framework work like hilt.

When you should use Anvil?

You should use Anvil, when your application is already using Dagger with thousands of modules & many dagger components and it is inconceivable for you to migrate your codebase to hilt, then choosing a plugin like Anvil would do the magic for you by merging your modules and components interface automatically.

You can check the complete project with dagger and anvil setup here:

Anvil official github repository : https://github.com/square/anvil/

--

--