带有贡献者的 Dagger 子组件

Dagger subcomponent with contributor

我在注入我通过 @ContributesAndroidInjector 贡献的片段时遇到问题。

我正在尝试在模块(功能)内构建层次结构。基本上,我所拥有的是:

我的 AppComponent 取决于 CoreComponent:

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

    fun getApp(): Application

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

并初始化为:

@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
    }
}

这部分非常简单。 AppComponent 有 ActivityContributor 而只有一个 @ContributesAndroidInjector,即 MainActivity.

现在,当我想添加一个封装的功能子组件时,问题就出现了。假设我的功能中有两个片段 FragmentOneFragmentTwo,具有一些共同的依赖项以及它们自己的依赖项。

我想要的是 FeatureSubcomponent,其中有 FeatureModuleFeatureContributor:

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

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

虽然 FeatureModule 具有两个片段共有的依赖关系,但 FeatureContributor 贡献了 FragmentOneFragmentTwo 自己的模块:

@Module
abstract class FeatureContributor {

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

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

当然,我将 FeatureSubcomponent 作为子组件添加到 AppModule:

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

如果向上滚动,您会看到 AppModule 包含在 AppComponent 的模块中。

问题是,在编译和 运行 时,由于 No injector factory bound for 错误,它一旦到达任何功能片段就会崩溃。

大致总结一下我的结构:

任何人都知道为什么或应该如何代替它,或者我是否遗漏了什么?

编辑

这是我准备的图表,以便于理解层次结构

Dagger android 通过在当前范围内找到最近的注入器来进行注入。对于 Fragment,它是包含 Activity,对于 Activity,它是 Application 实例。

当您在 Fragment 中调用 AndriodInject.inject(this) 时,它会在层次结构中向上查找注入器,然后注入 Fragment。

您是否扩展了 DaggerAppCompatActivity/实施了 HasFragmentInjector

我看到的另一件事是,@ContributesAndroidInjector 已经在内部为您创建了一个子组件,为什么还要再创建一个子组件?

@ContributesAndroidInjector.modules 是一种与生成的子组件对话的方式。因此,必须在 @ContributesAndroidInjector 将生成的子组件中建立 Activity 和 FeatureFragment 之间的 关系。

现在你的层次结构是这样的,因为你故意指定 FeatureSubComponent 作为 AppComponent

的子组件
App -> FeatureSubComponent -> [A, B] (generated)
      \
       \---> MainActivitySubcomponent (generated by contributesAndroidInjector).

您实际需要的是:

App -> MainActivitySubComponent (generated) -> [Feature A , Feature B] (generated)

这样做

@ContributesAndroidInjector(modules = [FeatureContributor::class])
abstact fun mainActivity() : MainActivity

功能贡献者可以有 @ContributesAndroidInjectors 里面。当 Dagger 编译器发现 FeatureContributor@ContributesAndroidInjectors 时,它使那些生成的子组件成为 activity 的子组件,因为它是父组件。

这基本上意味着 Activity -> Fragment 层次结构。