Progress Β· 0/10 sections
π π Dependency Injection (Hilt)
2 min read Β· Notion
What is Dependency Injection?
Dependency Injection is a design pattern where objects receive their dependencies from outside rather than creating them internally:
// Without DI (tight coupling)
class UserViewModel {
private val repo = UserRepositoryImpl() // creates own dependency
}
// With DI (loose coupling)
class UserViewModel(private val repo: UserRepository) // injectedBenefits: testability, swappable implementations, separation of concerns.
What is Hilt and how does it differ from Dagger?
Hilt is a Jetpack DI framework built on top of Dagger that reduces boilerplate:
| Dagger | Hilt | |
|---|---|---|
| Setup | Manual components/modules | Auto-generated components |
| Android integration | Manual | Built-in for Activity/Fragment/ViewModel |
| Scope | Custom | Predefined (Singleton, ActivityScoped, etc.) |
| Learning curve | Steep | Simpler |
Hilt auto-generates components for standard Android classes.
Setting up Hilt
@HiltAndroidApp
class MyApp : Application()
@AndroidEntryPoint
class MainActivity : AppCompatActivity()
@HiltViewModel
class UserViewModel @Inject constructor(
private val repo: UserRepository
) : ViewModel()
@Module
@InstallIn(SingletonComponent::class)
object AppModule {
@Provides
@Singleton
fun provideUserRepo(api: UserApi, dao: UserDao): UserRepository =
UserRepositoryImpl(api, dao)
}Hilt Scopes
| Scope Annotation | Component | Lifetime |
|---|---|---|
@Singleton | SingletonComponent | App lifetime |
@ActivityScoped | ActivityComponent | Activity lifetime |
@ViewModelScoped | ViewModelComponent | ViewModel lifetime |
@FragmentScoped | FragmentComponent | Fragment lifetime |
Always scope at the minimum necessary lifetime to avoid memory leaks.
Injecting interfaces with @Binds
@Module
@InstallIn(SingletonComponent::class)
abstract class RepositoryModule {
@Binds
abstract fun bindUserRepo(impl: UserRepositoryImpl): UserRepository
}@Binds is more efficient than @Provides for binding interface to implementation.
Using @Qualifier for multiple implementations
@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class RemoteDataSource
@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class LocalDataSource
// Inject specific one:
class UserRepo @Inject constructor(
@RemoteDataSource private val remoteSource: UserDataSource,
@LocalDataSource private val localSource: UserDataSource
)