带有命名参数的 Kotlin 中的 Dagger 2 构造函数注入
Posted
技术标签:
【中文标题】带有命名参数的 Kotlin 中的 Dagger 2 构造函数注入【英文标题】:Dagger 2 constructor injection in kotlin with Named arguments 【发布时间】:2018-07-04 16:29:45 【问题描述】:我有这个依赖:
@Singleton
class SpiceMix @Inject constructor(@field:[Named("oregano")] private val oregano: Spice,
@field:[Named("sage")] private val sage: Spice,
@field:[Named("rosemary")] private val rosemary: Spice)
还有一个模块来实现它的依赖:
@Module
class SpiceModule
@Provides
@Named("oregano")
@Singleton
fun provideOregano(): Spice = Oregano()
@Provides
@Named("sage")
@Singleton
fun provideSage(): Spice = Sage()
@Provides
@Named("rosemary")
@Singleton
fun provideRosemary(): Spice = Rosemary()
然后将SpiceMix
注入我的应用程序的各个位置。
但是,这不能编译,我得到一个错误:
Spice cannot be provided without an @Provides-annotated method
我认为@Named 注释在我的构造函数签名中不太适用。我不太确定如何让它发挥作用。
注意:如果我放弃命名注释并将构造函数参数的类型更改为它们的具体形式,这编译得很好。但是,Spice 是一个接口,我在测试中需要它来模拟目的。
我能做什么?
【问题讨论】:
【参考方案1】:如果您正在执行构造函数注入,您想要注释构造函数参数,而不是字段 - 使用 @param:
注释目标:
@Singleton
class SpiceMix @Inject constructor(@param:Named("oregano") private val oregano: Spice,
@param:Named("sage") private val sage: Spice,
@param:Named("rosemary") private val rosemary: Spice)
编辑:实际上,因为注释目标的解析顺序是
参数; 财产; 字段。
根据docs,没有注解目标也应该注解构造函数的参数。所以你可以完全放弃目标:
@Singleton
class SpiceMix @Inject constructor(@Named("oregano") private val oregano: Spice,
@Named("sage") private val sage: Spice,
@Named("rosemary") private val rosemary: Spice)
【讨论】:
是的!谢谢!像魅力一样工作 嘿!很高兴听到,也请查看我编辑的答案 - 我意识到还有一个更简单的解决方案。 哈!如果我只是尝试了好的 ol' Java 方式,它就会成功。不过,今天我学会了!谢谢。以上是关于带有命名参数的 Kotlin 中的 Dagger 2 构造函数注入的主要内容,如果未能解决你的问题,请参考以下文章
没有Dagger2的Android Kotlin MVVM结构
ViewModel 中的 Kotlin Dagger 字段注入引发 Dagger/Binding 异常
Dagger2 Qualifier 不适用于 Kotlin?