Search code examples
dagger-2dagger-hilt

How to provide Retrofit in non-Android Module to an Android module?


Let me be more clear:

I have a multi-module app. There's the :app module, which is an Android module that I'm using Hilt to take care of dependency injection, and I also created a :network module that will only be used to provide an instance of Retrofit to any class that injects it. I don't need nothing related to Android in the :network module since it's pretty basic.

The build.gradle in my :network module is as follows:

plugins {
    id("java-library")
    alias(libs.plugins.jetbrainsKotlinJvm)
    alias(libs.plugins.ksp)
}

dependencies {
    implementation(libs.retrofit)
    implementation(libs.retrofit.moshi.converter)
    implementation(libs.moshi)
    implementation(libs.moshi.kotlin)
    implementation(libs.hilt.core) // com.google.dagger:hilt-core:

    ksp(libs.dagger.compiler)
    ksp(libs.moshi.codegen)
}

And my module is being declared as:

@InstallIn(SingletonComponent::class)
@Module
object NetworkModule {
    @Provides
    @Singleton
    fun provideMoshi(): Moshi = Moshi.Builder().apply {
        addLast(KotlinJsonAdapterFactory())
    }.build()

    @Provides
    @Singleton
    fun provideRetrofit(
        moshi: Moshi,
    ): Retrofit = Retrofit.Builder().apply {
        baseUrl(REST_COUNTRIES_URL)
        addConverterFactory(MoshiConverterFactory.create(moshi))
    }.build()
}

Finally, my ViewModel (in the :app module) injects Retrofit:

@HiltViewModel
class MainActivityViewModel @Inject constructor(
    val databaseStuff: DatabaseInterface,
    val retrofit: Retrofit,
) : ViewModel() {
    // ... ViewModel code
}

In my head this should work, but instead I get that familiar "Missing binding usage" error:

Missing binding usage:
      retrofit2.Retrofit is injected at
          blabla.MainActivityViewModel(…, retrofit)
      blabla.MainActivityViewModel is injected at
          blabla.MainActivityViewModel_HiltModules.BindsModule.binds(arg0)
      @dagger.hilt.android.internal.lifecycle.HiltViewModelMap java.util.Map<java.lang.String,javax.inject.Provider<androidx.lifecycle.ViewModel>> is requested at
          dagger.hilt.android.internal.lifecycle.HiltViewModelFactory.ViewModelFactoriesEntryPoint.getHiltViewModelMap() [blabla.MyApplication_HiltComponents.SingletonC → blabla.MyApplication_HiltComponents.ActivityRetainedC → blabla.MyApplication_HiltComponents.ViewModelC]

What exactly am I missing here? This, in my head, should be working. However, I don't really know the ins and outs of how Dagger works behind the scenes, honestly.


Solution

  • Changing ksp(libs.dagger.compiler) to ksp(libs.hilt.compiler) in the build.gradle of my :network module worked. That was literally it.