Dagger2 - 多模块 - 组件中存在具有匹配键的绑定
Dagger2 - Multi Module - A binding with matching key exists in component
背景
我正在尝试在多模块设置中使用 Dagger。我的目标之一是减少使用的组件数量。所以基本上每个功能模块的目标是 1 个组件。
设置核心->应用->功能
问题
Dagger 失败,异常 A binding with matching key exists in component:
指的是 I have bound a dependency somewhere in my entire object graph but it cannot be reached.
但对于我的场景,我在 activity 中创建子组件并调用 inject 以确保该组件可以访问我的 activity。这至少在我的理解中应该是可以访问的,但它仍然无法提供我的视图模型的依赖性。
这里是 sample/multi-module 以防有人想尝试。
堆栈跟踪
/Users/feature1/build/**/FeatureComponent.java:8: error: [Dagger/MissingBinding]
com.**.FeatureActivity cannot be provided without an @Inject constructor or an @Provides-annotated
method. This type supports members injection but cannot be implicitly provided.
public abstract interface FeatureComponent {
^
A binding with matching key exists in component: com.**.FeatureComponent
com.**.FeatureActivity is injected at
com.**.FeatureModule.provideVM(activity)
com.**.FeatureViewModel is injected at
com.**.FeatureActivity.vm
com.**.FeatureActivity is injected at
com.**.FeatureComponent.inject(com.**.FeatureActivity)
应用组件
@AppScope
@Component(dependencies = [CoreComponent::class])
interface AppComponent {
fun inject(app: MainApp)
@Component.Factory
interface Factory {
fun create(
coreComponent: CoreComponent
): AppComponent
}
}
核心组件
@Singleton
@Component
interface CoreComponent {
fun providerContext(): Context
@Component.Factory
interface Factory {
fun create(
@BindsInstance applicationContext: Context
): CoreComponent
}
}
特征组件
@Component(
modules = [FeatureModule::class],
dependencies = [CoreComponent::class]
)
@FeatureScope
interface FeatureComponent {
// Planning to use this component as a target dependency for the module.
fun inject(activity: FeatureActivity)
}
功能模块
@Module
class FeatureModule {
@Provides
fun provideVM(activity: FeatureActivity): FeatureViewModel {
val vm by activity.scopedComponent {
FeatureViewModel()
}
return vm
}
}
功能虚拟机
class FeatureViewModel @Inject constructor(): ViewModel()
因为我使用 activity
来提供我的 viewModel
我将不得不使用 @BindsInstance
来绑定我想要的任何 activity 或片段的实例注入。
简而言之,如果我将我的功能组件更改为以下代码,它将开始工作,我在创建组件时绑定 activity 的实例。
PS: 如果有人知道在后期只使用一个组件注入片段的更好方法,请随时改进这个答案。
要素组件
@Component(
modules = [FeatureModule::class],
dependencies = [CoreComponent::class]
)
@FeatureScope
interface FeatureComponent {
fun inject(activity: FeatureActivity)
@Component.Factory
interface Factory {
fun create(
@BindsInstance applicationContext: FeatureActivity,
coreComponent: CoreComponent,
): FeatureComponent
}
}
背景
我正在尝试在多模块设置中使用 Dagger。我的目标之一是减少使用的组件数量。所以基本上每个功能模块的目标是 1 个组件。
设置核心->应用->功能
问题
Dagger 失败,异常 A binding with matching key exists in component:
指的是 I have bound a dependency somewhere in my entire object graph but it cannot be reached.
但对于我的场景,我在 activity 中创建子组件并调用 inject 以确保该组件可以访问我的 activity。这至少在我的理解中应该是可以访问的,但它仍然无法提供我的视图模型的依赖性。
这里是 sample/multi-module 以防有人想尝试。
堆栈跟踪
/Users/feature1/build/**/FeatureComponent.java:8: error: [Dagger/MissingBinding]
com.**.FeatureActivity cannot be provided without an @Inject constructor or an @Provides-annotated
method. This type supports members injection but cannot be implicitly provided.
public abstract interface FeatureComponent {
^
A binding with matching key exists in component: com.**.FeatureComponent
com.**.FeatureActivity is injected at
com.**.FeatureModule.provideVM(activity)
com.**.FeatureViewModel is injected at
com.**.FeatureActivity.vm
com.**.FeatureActivity is injected at
com.**.FeatureComponent.inject(com.**.FeatureActivity)
应用组件
@AppScope
@Component(dependencies = [CoreComponent::class])
interface AppComponent {
fun inject(app: MainApp)
@Component.Factory
interface Factory {
fun create(
coreComponent: CoreComponent
): AppComponent
}
}
核心组件
@Singleton
@Component
interface CoreComponent {
fun providerContext(): Context
@Component.Factory
interface Factory {
fun create(
@BindsInstance applicationContext: Context
): CoreComponent
}
}
特征组件
@Component(
modules = [FeatureModule::class],
dependencies = [CoreComponent::class]
)
@FeatureScope
interface FeatureComponent {
// Planning to use this component as a target dependency for the module.
fun inject(activity: FeatureActivity)
}
功能模块
@Module
class FeatureModule {
@Provides
fun provideVM(activity: FeatureActivity): FeatureViewModel {
val vm by activity.scopedComponent {
FeatureViewModel()
}
return vm
}
}
功能虚拟机
class FeatureViewModel @Inject constructor(): ViewModel()
因为我使用 activity
来提供我的 viewModel
我将不得不使用 @BindsInstance
来绑定我想要的任何 activity 或片段的实例注入。
简而言之,如果我将我的功能组件更改为以下代码,它将开始工作,我在创建组件时绑定 activity 的实例。
PS: 如果有人知道在后期只使用一个组件注入片段的更好方法,请随时改进这个答案。
要素组件
@Component(
modules = [FeatureModule::class],
dependencies = [CoreComponent::class]
)
@FeatureScope
interface FeatureComponent {
fun inject(activity: FeatureActivity)
@Component.Factory
interface Factory {
fun create(
@BindsInstance applicationContext: FeatureActivity,
coreComponent: CoreComponent,
): FeatureComponent
}
}