【问题标题】:Dagger/MissingBinding error when creating a subcomponent创建子组件时出现 Dagger/MissingBinding 错误
【发布时间】:2022-01-17 06:15:06
【问题描述】:

我正在尝试使用 Dagger 子组件,但遇到了一个我难以理解的错误。

所以基本上我有一个Subcomponent 和一个Component

// FeatureComponent.kt, @Subcomponent

@Scope
annotation class Feature

@Subcomponent(modules = [FeatureModule::class])
@Feature
interface FeatureComponent {
    fun inject(loginActivity: LoginActivity)

    @Subcomponent.Builder
    interface Builder {
        fun build(): FeatureComponent
    }
}

@Module
class FeatureModule {
    @Provides
    @Feature
    fun provideFeatureStorage(): FeatureStorage {
        return FeatureStorage()
    }
}

@Feature
class FeatureStorage

还有Component

@Component(modules = [LoginModule::class])
@Singleton
interface LoginComponent {
    fun loginComponent(): LoginComponent
    fun inject(loginActivity: LoginActivity)

    @Component.Builder
    interface Builder {
        fun build(): LoginComponent
    }

    fun featureComponent(): FeatureComponent.Builder // declare the subcomponent
}

@Module(subcomponents = [FeatureComponent::class])
class LoginModule {
    @Provides
    @Singleton
    fun provideSingletonInstance(): Storage {
        return Storage()
    }

    @Provides
    fun provideNotSingletonInstance(): UserSession {
        return UserSession()
    }
}

class Storage
class UserSession

我正在尝试在这样的活动中注入@Subcomponent 提供的FeatureStorage

class LoginActivity : AppCompatActivity() {
    @Inject
    lateinit var featureStorage: FeatureStorage

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_second)

        loginComponent.inject(this)
        loginComponent.featureComponent().build().inject(this)
    }

}

但是 Dagger 编译失败:

[Dagger/MissingBinding] com.vgrec.daggerkurs.components.FeatureStorage 如果没有 @Inject 构造函数或 @Provides-annotated 方法。

组件中存在具有匹配键的绑定: com.vgrec.daggerkurs.components.FeatureComponent com.vgrec.daggerkurs.components.FeatureStorage 被注入 com.vgrec.daggerkurs.components.LoginActivity.featureStorage com.vgrec.daggerkurs.components.LoginActivity 注入于 com.vgrec.daggerkurs.components.LoginComponent.inject(com.vgrec.daggerkurs.components.LoginActivity)

这部分:FeatureStorage cannot be provided without an @Inject constructor or an @Provides-annotated method 看起来很奇怪,因为FeatureStorage 是使用@Provides 注释提供的。

有什么想法可能在我的设置中出错吗?

【问题讨论】:

    标签: android dagger-2


    【解决方案1】:

    Dagger 不能部分注入一个类; FeatureComponent 知道如何注入 FeatureStorage,但您已指示 LoginComponent 尝试注入 LoginActivity,因此 LoginComponent 将无法成功搜索 @Provides FeatureStorage 方法。

    由于您可以将 FeatureComponent 创建为 LoginComponent 的子组件,因此不应存在 LoginComponent 可以注入而 FeatureComponent 不能注入的绑定。因此,我会从 LoginComponent 中删除 inject 方法,并允许您创建的 FeatureComponent 成为注入 LoginActivity 的唯一类。

    作为替代方案,您可以在 LoginActivity 中从 featureStorage 中删除 @Inject,而是在 FeatureComponent 上公开 featureStorage() 方法。在这种情况下,您可以自己保存并实例化它,而不是通过inject(LoginActivity) 实例化 FeatureStorage。

    但是,在所有情况下,我不得不承认我发现您的图表令人困惑,我希望其他读者也会: FeatureComponent 和 LoginComponent 之间的关系不清楚,我不知道为什么这些生命周期会分开或真的首先期望 FeatureComponent 具有什么样的生命周期。在 Android 中,设置与 Application 和 Activity 生命周期相匹配的 Dagger 图结构更为常见,像 Hilt 这样的系统将这些组件内置在框架中。

    【讨论】:

    • 谢谢你的解释,现在很有意义!这确实解决了这个问题。我也同意你关于 FeatureComponent 和 LoginComponent 之间的关系混淆的评论:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-04-23
    • 2021-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多