Search code examples
androidkotlindagger-hilt

component dependencies in Hilt


Good day, I have experience in dagger2 but I'm trying to gain some experience in Hilt so I start with the demo application by migrating the demo from Dagger2 to Hilt. in my Dagger app, I have two components ApplicationComponent and ActivityComponent. ActivityComponent depends on the ApplicationComponent so I wrote ActivityComponent as following:-

@ActivityScope
@Component(
    dependencies = [ApplicationComponent::class],
    modules = [ActivityModule::class]
)
interface ActivityComponent {
    fun inject(dummyActivity: DummyActivity)
    fun inject(dummyActivity2: DummyActivity2)
}

so I tried to achieve the same behavior in Hilt. I know Hilt users never define or instantiate Dagger components directly. Instead, Hilt offers predefined components that are generated for us, and as the documentation explains "child component can have dependencies on any binding in an ancestor component" enter image description here

so i thought i can do the following as ActivityComponent is a child of the SingletonComponent/ ApplicationComponent so ActivityComponent can access any bindings in the ApplicationComponent:-

@Module
@InstallIn(ApplicationComponent::class)
class  ApplicationModule {


    @Provides
    @Singleton
    fun provideDispatcherProvider(): DispatcherProvider = FlowDispatcherProvider()

    @Provides
    @Singleton
    fun provideSharedPreferences(@ApplicationContext application: Application): SharedPreferences =
        application.getSharedPreferences("project-prefs", Context.MODE_PRIVATE)

   
    @Provides
    @Singleton
    fun provideNetworkHelper(@ApplicationContext application: Application): NetworkHelper = NetworkHelper(application)

@Provides
@Singleton
fun provideNetworkService(@ApplicationContext application: Application): NetworkService =
        Networking.create(
            BuildConfig.USERNAME,
            BuildConfig.PASSWORD,
            BuildConfig.BASE_URL,
            application.cacheDir,
            10 * 1024 * 1024 // 10MB
        )

}


@Module
@InstallIn(ActivityComponent::class)
class ActivityModule {


    @Provides
    @ActivityScoped
    fun provideMyHelper(
        dispatcherProvider: DispatcherProvider,
        networkHelper: NetworkHelper
       ):MyHelper =  MyHelper(dispatcherProvider, networkHelper)


}

class MyHelper
    (
    private val dispatcherProvider: DispatcherProvider,
    private val networkHelper: NetworkHelper
) {

}

@ActivityScoped
@AndroidEntryPoint
class DummyActivity(): AppCompatActivity() {

    @Inject
    lateinit var myhelper: MyHelper
}

but when I try to build this code I get:-

error: [Dagger/MissingBinding] @com.mypackage.ApplicationContext android.app.application cannot be provided without an @Provides-annotated method.
  public abstract static class SingletonC implements MyApplication_GeneratedInjector,
                         ^
      @com.mypackage.ApplicationContext android.app.Application is injected at
          mypackage.module.ApplicationModule.provideNetworkHelper(application)
      com.mypackage.NetworkHelper is injected at
          com.mypackage.ActivityModule.provideMyHelper(�, networkHelper)
      com.mypackage.MyHelper is injected at
          com.mypackage.DummyActivity.myhelper
      com.mypackage.DummyActivity is injected at
      com.mypackage.DummyActivity.myhelper

so what am I missing here? Thanks in advance


Solution

  • Apparently you do not import the ApplicationContext qualifier correctly, it should be dagger.hilt.android.qualifiers.ApplicationContext.