Skip to content
tezvyn:

Functional difference between @Binds and @Provides in Hilt

Source: developer.android.comMediumHow cards are made

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's really being asked

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.

The mistakes people make

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.

What usually comes next

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.

A 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.

Interview question

Your teammate binds an interface to its @Inject-annotated implementation using @Provides in a concrete module. What is the main drawback compared to using @Binds?

  • a.There is no drawback; @Provides is simply a more verbose shorthand for @Binds in this case
  • b.It silently disables the implementation's @Inject constructor and breaks injection elsewhere
  • c.It adds unnecessary overhead by generating a factory even though Dagger already knows how to construct the typeCorrect
  • d.It fails compilation because @Provides methods must return concrete classes, not interfaces
Why?

@Provides generates an intermediate factory even when the implementation already has an @Inject constructor, whereas @Binds links the interface to that implementation without extra generated code. Option A is wrong because @Provides is not merely a shorthand; it creates unnecessary overhead and serves a different purpose.

Just read this? Test yourself on what you have been reading.

Read the original → developer.android.com

You just looked this up. Could you explain it out loud?

That is the part interviews actually test. Tezvyn takes questions like this one and gives you what the interviewer is really checking, the answer that lands, and the mistake that ends the conversation, in the four minutes before your next meeting.

The iPhone app is on the way

We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.

Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.

Get it on Google PlayiPhone app coming soon

We are hiring for this. Open roles that interview on android — each one lists the topics its interview covers.

See open roles