PPrepLearn
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) // injected

Benefits: 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:

DaggerHilt
SetupManual components/modulesAuto-generated components
Android integrationManualBuilt-in for Activity/Fragment/ViewModel
ScopeCustomPredefined (Singleton, ActivityScoped, etc.)
Learning curveSteepSimpler

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 AnnotationComponentLifetime
@SingletonSingletonComponentApp lifetime
@ActivityScopedActivityComponentActivity lifetime
@ViewModelScopedViewModelComponentViewModel lifetime
@FragmentScopedFragmentComponentFragment 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
)

Related