Dagger2:依赖项与模块

问题描述 投票:0回答:2

下面的实现给出错误提示无法提供 DataStore。我假设当 UserPreferencesComponent 作为 CreateAccountComponent 的依赖项包含时,UserPreferencesModule 将提供此功能。对我来说,解决这个问题的方法是省略该组件并直接包含该模块。

@Module
class UserPreferencesModule {

    @Provides
    @Singleton
    fun provideUserPreferencesDataStore(context: Context): DataStore<UserPreferences> = context.userPreferences

    @Provides
    @Singleton
    fun provideUserPreferencesManager(userPreferences: DataStore<UserPreferences>): UserPreferencesManager = UserPreferencesManager(userPreferences)

}


@Component(modules = [UserPreferencesModule::class], dependencies = [CommonProvider::class])
interface UserPreferencesComponent

@Component(
    modules = [
        CreateAccountModule::class,
    ],
    dependencies = [
        AuthDomainComponent::class,
        UserDomainComponent::class,
        UserPreferencesComponent::class
        CommonProvider::class
    ]
)
@Singleton
interface CreateAccountComponent {
    val createAccountViewModel: CreateAccountViewModel
}

我正在寻找解释为什么我的假设是错误的

android dagger-2
2个回答
0
投票

我认为原因是

UserPreferencesComponent
没有提供任何东西。在组件中添加提供功能并重试。


0
投票

Dagger 组件依赖项 具有非常具体的行为:每个“提供方法”(可能限定的零参数方法)在声明依赖项的组件图中变得可用。您在

dependencies
中列出的类型可以是任意接口,不必生成或使用 Dagger 注释进行注释,尽管它们的设计目的是允许 Dagger 生成的组件以这种方式轻松工作。

因为它们都是顶级

@Component
,所以 UserPreferencesComponent 和 CreateAccountComponent 的代码生成步骤将分别发生,UserPreferencesComponent 不知道 CreateAccountComponent 对其的依赖关系。 Dagger 删除未使用的绑定,并且由于 UserPreferencesComponent 接口未声明任何提供或注入方法,因此生成的实现 DaggerUserPreferencesComponent 实际上将为空:CreateAccountComponent 没有任何内容可调用。

要按照您尝试的方式使用组件依赖项,您将需要 UserPreferencesComponent 来声明类似

fun getUserPreferencesDataStore(): DataStore<UserPreferences>
的方法。名称并不重要,但函数的签名非常重要,因为这将告诉任何表达对 UserPreferencesComponent 的依赖的 Dagger 组件,它将可以访问
DataStore<UserPreferences>
,就像它是在模块的
@Provides 中指定的一样
方法。同时在
@Component
上声明该方法使其成为 UserPreferencesComponent 的入口点,因此 Dagger 有理由通过调用
UserPreferencesModule.provideUserPreferencesDataStore()
来实现该方法。请注意,您必须在 CreateAccountComponent.Builder 或 CreateAccountComponent.Factory 中提供 UserPreferencesComponent 的实现(可能是您实例化的 DaggerUserPreferencesComponent),因为 Dagger 无法在 UserPreferencesComponent 上调用无参数
new

如果您不需要组件依赖项提供的解耦,您可以直接重用已有的模块。您还可以考虑使用子组件进行封装,但如果这样做,您仍然需要通过

@Provides
方法显式地使子组件的选定绑定在父组件中显式可用。

© www.soinside.com 2019 - 2024. All rights reserved.