Functional difference between @Binds and @Provides in Hilt

Tests if you understand Hilt code generation tradeoffs. @Binds wires an existing injectable implementation to an interface with less overhead; @Provides constructs instances manually.
WHAT THIS TESTS: Whether you understand the difference between telling Dagger how to build something versus telling it which implementation to use for an abstraction. It also checks if you know the compile-time implications and the structural requirements of Hilt modules.
A GOOD ANSWER COVERS four things in order. First, define @Binds as an abstract method inside an abstract module that maps an already-injectable implementation to an interface or superclass. Because the implementation has an @Inject constructor, Dagger already knows how to construct it, so @Binds generates no extra factory code and is more efficient. Second, define @Provides as a concrete method inside a concrete module that acts as a factory. It can contain arbitrary logic, instantiate classes that lack @Inject constructors, and assemble configured objects. Third, explain the must-use scenario for @Provides: whenever the implementation is from a third-party library, has no @Inject constructor, or requires manual configuration such as calling builders or setting properties before returning the instance. Fourth, note the structural rules: @Binds methods must be abstract and sit in an abstract class or interface, while @Provides methods must be concrete and sit in a concrete class.
COMMON WRONG ANSWERS: Claiming that @Binds is just a shorthand for @Provides and can be used in any situation. Saying that @Binds can run setup logic or call constructors directly. Forgetting that @Binds requires the implementation type to already be available in the graph, which means it needs an @Inject constructor or another binding. Another red flag is not knowing that mixing @Binds and @Provides in the same module requires the module to be abstract with concrete static @Provides methods or splitting them into separate modules.
LIKELY FOLLOW-UPS: The interviewer may ask why @Binds generates less code, which is because Dagger can directly link the implementation's constructor injection without generating an intermediate Provider. They might ask how to bind an interface when the implementation needs configuration, where the correct pattern is either using @Provides for everything or using @Binds for the interface and @Provides for the configured dependencies. They may also ask about the performance or build-speed difference, or what happens if you put @Binds in a non-abstract module.
ONE CONCRETE EXAMPLE: Suppose you have a UserRepository interface and a UserRepositoryImpl with an @Inject constructor. You should use an abstract module with @Binds to map UserRepositoryImpl to UserRepository. However, if UserRepositoryImpl requires a RoomDatabase that you build with Room.databaseBuilder, or an OkHttpClient that you configure with interceptors and timeouts, you cannot use @Binds because you need to execute builder methods. In that case, you must use a concrete module with a @Provides method that constructs and configures the object before returning it.
Source: developer.android.com
Read the original → developer.android.com
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.