带贡献者的Dagger子组件

时间:2019-05-20 12:08:01

标签: android dependency-injection dagger-2

我无法插入通过@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,并且有一些共同的依赖性以及它们自己的依赖性。

我想拥有一个FeatureSubcomponentFeatureModule的{​​{1}}:

FeatureContributor

虽然@FeatureScope @Subcomponent( modules = [FeatureContributor::class, FeatureModule::class ] ) abstract class FeatureSubcomponent { @Subcomponent.Factory interface Factory { fun create(): FeatureSubcomponent } } 具有两个片段共有的依赖关系,但是FeatureModule贡献FeatureContributorFragmentOne带有它们自己的模块:

FragmentTwo

当然,我将@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错误,一旦到达任何功能片段,它就会崩溃。

大致总结一下我的结构:

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

任何人都有关于为什么或应该怎么做的想法,或者我是否缺少某些东西?

修改

这是我准备用来简化层次结构的图

Dagger hierarchy diagram

1 个答案:

答案 0 :(得分:1)

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 -> Fragment层次结构。