带有贡献者的 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
.
现在,当我想添加一个封装的功能子组件时,问题就出现了。假设我的功能中有两个片段 FragmentOne
和 FragmentTwo
,具有一些共同的依赖项以及它们自己的依赖项。
我想要的是 FeatureSubcomponent
,其中有 FeatureModule
和 FeatureContributor
:
@FeatureScope
@Subcomponent(
modules = [FeatureContributor::class,
FeatureModule::class
]
)
abstract class FeatureSubcomponent {
@Subcomponent.Factory
interface Factory {
fun create(): FeatureSubcomponent
}
}
虽然 FeatureModule
具有两个片段共有的依赖关系,但 FeatureContributor
贡献了 FragmentOne
和 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
的模块中。
问题是,在编译和 运行 时,由于 No injector factory bound for
错误,它一旦到达任何功能片段就会崩溃。
大致总结一下我的结构:
- 核心组件
- AppComponent
- 要素组件(子)
- FeatureOneComponent (SUB)
- FeatureTwoComponent (SUB)
任何人都知道为什么或应该如何代替它,或者我是否遗漏了什么?
编辑
这是我准备的图表,以便于理解层次结构
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
层次结构。
我在注入我通过 @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
.
现在,当我想添加一个封装的功能子组件时,问题就出现了。假设我的功能中有两个片段 FragmentOne
和 FragmentTwo
,具有一些共同的依赖项以及它们自己的依赖项。
我想要的是 FeatureSubcomponent
,其中有 FeatureModule
和 FeatureContributor
:
@FeatureScope
@Subcomponent(
modules = [FeatureContributor::class,
FeatureModule::class
]
)
abstract class FeatureSubcomponent {
@Subcomponent.Factory
interface Factory {
fun create(): FeatureSubcomponent
}
}
虽然 FeatureModule
具有两个片段共有的依赖关系,但 FeatureContributor
贡献了 FragmentOne
和 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
的模块中。
问题是,在编译和 运行 时,由于 No injector factory bound for
错误,它一旦到达任何功能片段就会崩溃。
大致总结一下我的结构:
- 核心组件
- AppComponent
- 要素组件(子)
- FeatureOneComponent (SUB)
- FeatureTwoComponent (SUB)
- 要素组件(子)
任何人都知道为什么或应该如何代替它,或者我是否遗漏了什么?
编辑
这是我准备的图表,以便于理解层次结构
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
层次结构。