【问题标题】:Dagger subcomponent with contributor带有贡献者的 Dagger 子组件
【发布时间】:2019-05-20 12:08:00
【问题描述】:

我在注入我通过 @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 错误,一旦到达任何功能片段,它就会崩溃。

大概总结一下我的结构:

  • 核心组件
  • 应用组件
    • 功能组件 (SUB)
      • FeatureOneComponent (SUB)
      • FeatureTwoComponent (SUB)

任何人都知道为什么或应该如何,或者我错过了什么?

编辑

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

【问题讨论】:

    标签: android dependency-injection dagger-2


    【解决方案1】:

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

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

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

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

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

    现在你的层次结构是这样的,因为你故意指定FeatureSubComponentAppComponent 的子组件

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

    【讨论】:

      猜你喜欢
      • 2021-03-15
      • 2011-09-13
      • 1970-01-01
      • 2012-07-29
      • 2014-04-15
      • 1970-01-01
      • 2017-11-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多