Search code examples
kotlindependency-injectionandroid-jetpack-composedagger-hilt

Jetpack Compose: How to Provide Context for Dagger/Hilt


So I realized when testing my actual app that I still need to provide a Context (when running actual tests I just used val appContext = InstrumentationRegistry.getInstrumentation().targetContext so I just kinda forgot about it.

But now I'm running the actual app in the emulator and get this error on startup: error: [Dagger/MissingBinding] android.content.Context cannot be provided without an @Provides-annotated method.

My DI object looks like this:

@Module
@InstallIn(SingletonComponent::class)
object AppModule {
    @Provides
    @Singleton
    fun provideShotTrackerDatabase(context: Context): ShotTrackerDbAdapter {
        val db = ShotTrackerDbAdapter(context)

        return db.open()
    }

    @Provides
    @Singleton
    fun provideShotTrackerRepository(db: ShotTrackerDbAdapter): ShotTrackerRepository {
        return ShotTrackerRepository(db)
    }
}

Of course my ViewModel is pretty standard, here's the declaration:

@HiltViewModel
class FirearmsViewModel @Inject constructor (private val shotTrackerRepository: ShotTrackerRepository) : ViewModel() {

I guess I kinda assumed this would already be provided since it's easily accessible in a Composable via LocalContext.current, but it's not.


Solution

  • You can inject application: Application:

    @Provides
    @Singleton
    fun provideShotTrackerDatabase(application: Application): ShotTrackerDbAdapter {
         val db = ShotTrackerDbAdapter(application)
         return db.open()
    }
    

    Or @ApplicationContext context: Context as you already found:

    @Provides
    @Singleton
    fun provideShotTrackerDatabase(@ApplicationContext context: Context): ShotTrackerDbAdapter {
         val db = ShotTrackerDbAdapter(context)
         return db.open()
    }