Overview
NASA Explorer uses Hilt, a dependency injection library built on top of Dagger, to manage object creation and provide dependencies throughout the application. Hilt reduces boilerplate code and ensures proper scoping of dependencies.Why Dependency Injection?
Dependency injection provides several benefits:Loose Coupling
Components don’t create their own dependencies, making them more flexible and reusable
Testability
Easy to swap implementations for testing by providing mock dependencies
Lifecycle Management
Hilt manages object lifecycles, ensuring proper creation and cleanup
Code Reusability
Singleton instances are shared across the app, reducing memory overhead
Setting Up Hilt
Application Setup
The application class must be annotated with@HiltAndroidApp:
NasaExplorerApp.kt
This annotation triggers Hilt’s code generation including a base class for the application that serves as the application-level dependency container.
Activity Setup
Activities that use Hilt must be annotated with@AndroidEntryPoint:
MainActivity.kt
Hilt Modules
Modules define how to provide dependencies. NASA Explorer has three main modules:1. API Network Module
Provides networking dependencies for the NASA APOD API:data/di/ApiNetworkModule.kt
@InstallIn(SingletonComponent::class)
Specifies that dependencies are available throughout the entire application lifecycle
2. Firebase Module
Provides Firebase Database instance:data/di/FirebaseModule.kt
3. Auth Network Module
Provides Firebase Authentication instance:data/auth/AuthNetworkModule.kt
Constructor Injection
Repository Injection
TheNasaRepository receives its dependencies through constructor injection:
data/api/NasaRepository.kt
The
@Inject annotation tells Hilt to inject NasaApiService when creating the repository. Hilt automatically resolves the dependency from the ApiNetworkModule.Service Injection
TheAuthService receives Firebase Auth through constructor injection:
data/auth/AuthService.kt
ViewModel Injection
ViewModels use the@HiltViewModel annotation and receive dependencies through constructor injection:
ui/homescreen/HomeScreenViewModel.kt
ui/dailyimagescreen/DailyImageViewModel.kt
ViewModels are automatically injected into Composables using
hiltViewModel(). Hilt handles ViewModel creation and ensures proper scoping to the navigation destination.Dependency Graph
Here’s how dependencies flow through the application:Scopes in Hilt
Singleton Scope
Dependencies installed inSingletonComponent live for the entire application lifecycle:
ViewModel Scope
ViewModels are scoped to the navigation destination and survive configuration changes:Benefits of Hilt in NASA Explorer
Automatic Dependency Resolution
Automatic Dependency Resolution
Hilt automatically resolves the entire dependency graph. For example, when creating
DailyImageViewModel, Hilt knows it needs NasaRepository, which needs NasaApiService, which needs Retrofit, which needs OkHttpClient - all provided automatically.No Manual Instantiation
No Manual Instantiation
No need to manually create objects. Hilt handles instantiation and passes dependencies through constructors.
Proper Lifecycle Management
Proper Lifecycle Management
Singleton components live for the app lifecycle, ViewModels are scoped to navigation destinations, ensuring proper cleanup.
Testing Support
Testing Support
Easy to replace production modules with test modules for unit and integration testing.
Best Practices
Use Constructor Injection
Prefer constructor injection over field injection:Keep Modules Focused
Each module should provide related dependencies:ApiNetworkModule: Network-related dependenciesFirebaseModule: Firebase dependenciesAuthNetworkModule: Authentication dependencies
Use Singleton Appropriately
Only mark dependencies as@Singleton if they should be shared across the app:
Related Topics
MVVM Pattern
See how dependency injection works with ViewModels
Architecture Overview
Understand how DI fits into the overall architecture