Thursday 5 August 2021

Dagger subcomponent with contributor

I'm having trouble injecting a fragment that I contribute via @ContributesAndroidInjector.

I'm trying to build a hierarchy within modules (features). Basically, what I have is:

  • Core
  • App
  • Feature

My AppComponent depends on CoreComponent:

@Singleton
@Component(modules = [CoreModule::class])
interface CoreComponent {

    fun getApp(): Application

    @Component.Factory
    interface Factory {
        fun create(@BindsInstance app: Application): CoreComponent
    }
}

And initialize as:

@AppScope
@Component(
    modules = [
        AndroidInjectionModule::class,
        ActivityContributor::class,
        AppModule::class],
    dependencies = [CoreComponent::class]
)
interface AppComponent : AndroidInjector<App> {

    @Component.Factory
    interface Factory {
        fun create(component: CoreComponent): AppComponent
    }
}

This part is pretty much straightforward. AppComponent has ActivityContributor which only has one @ContributesAndroidInjector, which is MainActivity.

Now, problem starts when I want to add an encapsulated feature subcomponent. Assume I have two fragments FragmentOne and FragmentTwo in my feature, with some common dependencies as well as their own.

What I want to have is a FeatureSubcomponent which has FeatureModule and FeatureContributor:

@FeatureScope
@Subcomponent(
    modules = [FeatureContributor::class,
        FeatureModule::class
    ]
)
abstract class FeatureSubcomponent {

    @Subcomponent.Factory
    interface Factory {
        fun create(): FeatureSubcomponent
    }
}

While FeatureModule has dependencies common for both fragments, FeatureContributor is contributing FragmentOne and FragmentTwo with their own modules:

@Module
abstract class FeatureContributor {

    @ContributesAndroidInjector(modules = [FeatureOneModule::class])
    abstract fun featureOneFragment(): FeatureOneFragment

    @ContributesAndroidInjector(modules = [FeatureTwoModule::class])
    abstract fun featureTwoFragment(): FeatureTwoFragment
}

And of course, I add FeatureSubcomponent as a subcomponent to AppModule:

@Module(subcomponents = [FeatureSubcomponent::class])

And if you scroll up, you'll see AppModule is included in modules of AppComponent.

Problem is, while it's compiling and running, it crashes once it reaches to any feature fragments due to No injector factory bound for error.

Roughly summarising my structure:

  • CoreComponent
  • AppComponent
    • FeatureComponent (SUB)
      • FeatureOneComponent (SUB)
      • FeatureTwoComponent (SUB)

Anyone has ideas about why or how it should be instead or am I missing something ?

Edit

Here's the diagram I prepared to make it easier to understand hierarchy

Dagger hierarchy diagram



from Dagger subcomponent with contributor

No comments:

Post a Comment