下面的实现给出错误提示无法提供 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
}
我正在寻找解释为什么我的假设是错误的
我认为原因是
UserPreferencesComponent
没有提供任何东西。在组件中添加提供功能并重试。
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
方法显式地使子组件的选定绑定在父组件中显式可用。