Kotlin+Dagger best practices

Sree Kumar A.V
3 min readMar 22, 2021

1. Prefer constructor Injection over field injection

Use @Inject in the constructor.

When you do this Dagger will create a Factory for you !!!

Use Field injection only when Dagger can’t create an instance of your class, Like Activity, Fragments, those are created by the Android OS.

2. Prefer @Inject over @Provide

@Inject provides a factory for you, so use @Provide only when Dagger can’t resolve the dependencies by itself.

The above @Provide method is boilerplate, use a constructor injector in the EpicAppointmentFetchCoordinator.

3. Use static providers & make module abstract

Dagger can call static provider methods without creating the object of the module. That method call can be inlined by the compiler.

How this is different from the non-static provider method and abstract class?

appDiModuleParams is the instance of your module class, which is being passed in Factory class to call the provider method

4. Use @Binds while inferring the type.

When you use @Inject in the constructor of implementation, you need to use the bind to inform the dagger about your implementation mapping. If you don’t do that, you have to explicitly provide the implementation class using @Provide annotation

When exactly this can be useful?

As you know, when Dagger @Inject will create a factory like this

when you closely look at the get() method which returns GeofencingLocalRepoImpl. That means Dagger can provide you GeofencingLocalRepoImpl

without explicitly exposing a provider in the module. But we won’t inject the implementation detail, we need the interface reference instead.

GeoFencingUseCaseImpl is expecting a GeoFencingRepo : HOW CAN YOU TELL DAGGER TO DO THE MAPPING? ( GeofencingLocalRepoImpl → GeoFencingRepo )

@Binds will solve this issue by not exposing another provider method.

Reference:

https://github.com/google/dagger/issues/900
https://github.com/google/dagger/releases/tag/dagger-2.26

--

--