Dagger的@IntoSet注解在Kotlin Object模块中为何无法正常工作?
问题分析
你遇到的错误并不是@IntoSet注解不能在Kotlin Object模块中使用,而是Dagger对Kotlin Object类型模块的实例化处理逻辑导致的。
原因解释
Kotlin的object是单例类型,编译后会生成一个包含INSTANCE静态字段的类,理论上Dagger应该自动识别并使用这个单例实例来获取@Provides方法提供的依赖。但在某些情况下(比如Dagger版本较低,或者模块方法的声明方式不符合Dagger的预期),Dagger无法自动获取这个单例实例,就会错误地要求你手动设置模块实例,从而抛出"MyModuleA must be set"的错误。
而当你把模块改成普通Class时,Dagger会自动创建该类的实例(因为它有默认无参构造函数),所以不会触发这个错误。
解决方法
这里有几个可行的解决方案,你可以根据自己的情况选择:
升级Dagger到最新稳定版本
较新的Dagger版本(2.26及以后)对Kotlin的支持做了很多优化,能够正确识别Kotlinobject模块的单例特性,无需修改代码就能正常工作。为
@Provides方法添加@JvmStatic注解
在object模块的@Provides方法上加上@JvmStatic,让Dagger将其视为静态方法,这样就不需要模块实例即可调用方法提供依赖。修改后的MyModuleA如下:@Module object MyModuleA { @Provides @IntoSet @JvmStatic fun provideOneString(): String { return "ABC" } }通过模块包含来组织依赖(可选)
你也可以创建一个主模块,通过@Module(includes = [MyModuleA::class, MyModuleB::class])的方式将两个子模块包含进去,然后在Component中只声明主模块。不过这只是一种代码组织方式,不是必须的。
验证
按照上述方法修改后,运行你的测试代码,应该能正常输出包含ABC、DEF、GHI的Set集合。
内容的提问来源于stack exchange,提问作者Mumi

