android - 带有贡献者的 Dagger 子组件
问题描述
我无法注入我通过@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 has ActivityContributor
which 只有一个@ContributesAndroidInjector
,即MainActivity
.
现在,当我想添加一个封装的功能子组件时,问题就开始了。假设我有两个片段FragmentOne
,并且FragmentTwo
在我的功能中,有一些常见的依赖关系以及它们自己的依赖关系。
我想要的是一个FeatureSubcomponent
which has FeatureModule
and 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
错误而到达任何功能片段,它就会崩溃。
大致总结一下我的结构:
- 核心组件
- 应用组件
- 特征组件 (SUB)
- FeatureOneComponent (SUB)
- FeatureTwoComponent (SUB)
- 特征组件 (SUB)
任何人都知道为什么或应该如何,或者我错过了什么?
编辑
这是我准备的图表,以便更容易理解层次结构
解决方案
Dagger android 通过在当前范围内找到最近的注入器来进行注入。对于 Fragment,它是包含 Activity,对于 Activity,它是 Application 实例。
当您调用AndriodInject.inject(this)
Fragment 时,它会向上层级查找注入器,然后注入 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
has@ContributesAndroidInjectors
时,它会将那些生成的子组件作为活动的子组件,因为它是父组件。
这基本上意味着Activity -> Fragment
层次结构。
推荐阅读
- java - 添加 MariaDB 工件时出现 SchemaCrawler 错误
- google-chrome-extension - chrome.storage 不工作,并阻止下面的进程
- android - 在片段内执行 FragmentTransactions 是个好主意吗?
- r - ggplot2 中每个组的不同 scale_fill_gradient
- ios - 安排本地通知(静默)以在后台执行自定义任务 + swift ios
- jmeter - 如何将数组从 JSR223 采样器传递到另一个 JSR223 采样器?
- scala - 不兼容的 Jackson 版本:Spark Structured Streaming
- json - 以 JSON 格式登录到 cloudfoundry logstash
- c# - 使用 lambda 表达式更改列表中的字符串
- c# - 在 Azure VM 上,FtpWebRequest 处于活动模式(UsePassive = False)的“500 语法错误,命令无法识别”