Understanding the Difference Between @Provides and @Binds in Android Hilt

Steven
3 min readJul 18, 2023

--

Photo by Guido Coppa on Unsplash

Dependency Injection (DI) is a design pattern widely used in Android app development to improve code modularity, maintainability, and testability. DI frameworks, such as Android Hilt, provide annotations and mechanisms to facilitate dependency injection in Android projects. Two commonly used annotations in Hilt are @Provides and @Binds, which serve different purposes when defining dependencies. Understanding the difference between these annotations is crucial for effective dependency injection in your Android application.

@Provides Annotation

The @Provides annotation is used to define methods within a DI module that provide instances of dependencies. These methods are responsible for creating and providing instances of objects that will be injected into other parts of the application.

Here's an example of using @Provides in a Hilt module:

@Module
@InstallIn(SingletonComponent::class)
object DatabaseModule {

@Provides
@Singleton
fun provideDataBase(
@ApplicationContext context: Context
) : ApplicationDatabase {
return Room.databaseBuilder(
context.applicationContext,
ApplicationDatabase::class.java,
ApplicationDatabase.DB_NAME
).fallbackToDestructiveMigration()
.build()
}
}

In the above example, the provideDataBase() method is annotated with @Provides. This method is responsible for creating and returning an instance of the ApplicationDatabase abstract class. Hilt will use this method to provide instances of ApplicationDatabase whenever it is required for injection.

@Binds Annotation

The @Binds annotation, on the other hand, is used to declare that a certain interface should be bound to a specific implementation. Unlike @Provides, @Binds does not include the actual creation of instances but rather establishes a relationship between an interface and its implementation.

Consider the following example:

@Module
@InstallIn(ApplicationComponent::class)
interface MyModule {

@Binds
abstract fun bindMyDependency(impl: MyDependencyImpl): MyDependency
}

In this example, the bindMyDependency() method is annotated with @Binds. It declares that the MyDependency interface should be bound to the MyDependencyImpl implementation. The implementation instance is not created within the method; instead, it must be provided elsewhere, such as through constructor injection or other means.

Key Differences between @Provides and @Binds

  1. Object Creation: @Provides is responsible for creating and providing instances of dependencies, allowing you to write custom creation logic within the method. @Binds, on the other hand, does not handle object creation itself but establishes a relationship between an interface and its implementation.
  2. Interface Binding: @Binds is specifically used for binding an interface to its implementation, whereas @Provides can be used to provide instances of any type, including interfaces, classes, or other objects.
  3. Abstract Methods: @Binds methods must be declared as abstract within an abstract class or interface, while @Provides methods can be defined within regular classes.
  4. Code Simplicity: Using @Binds can lead to more concise code compared to @Provides, as it removes the need for explicit instance creation and focuses solely on binding the interface to its implementation.

Conclusion

In Android Hilt, both @Provides and @Binds annotations play important roles in dependency injection. The @Provides annotation is used to create and provide instances of dependencies, while the @Binds annotation establishes the relationship between an interface and its implementation. Understanding the differences between these annotations allows you to effectively use them in your DI modules and define dependencies in a clean and modular way.

By utilizing @Provides and @Binds appropriately, you can harness the power of dependency injection in Android development, improving code organization, maintainability, and testability. Take advantage of these annotations to simplify dependency management and build robust and scalable Android applications.

--

--

Steven

As an Android developer, I am constantly learning and expanding my knowledge to improve my skills and deliver better results.