具有命名参数的kotlin中的Dagger 2构造函数注入

Vas*_*Vas 25 android dependency-injection kotlin dagger-2

我有这种依赖:

@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) 
Run Code Online (Sandbox Code Playgroud)

以及一个实现其依赖关系的模块:

@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()
Run Code Online (Sandbox Code Playgroud)

SpiceMix然后在我的应用程序的不同位置注射.

但是,这不编译,我收到一个错误:

Spice cannot be provided without an @Provides-annotated method
Run Code Online (Sandbox Code Playgroud)

我认为@Named注释在我的构造函数签名中不起作用.我不太确定如何才能使它发挥作用.

注意:如果我抛弃Named注释并将构造函数参数的类型更改为其具体形式,则此编译很好.但是,Spice是一个接口,我需要它在我的测试中用于模拟目的.

我能做什么?

zsm*_*b13 28

如果您正在进行构造函数注入,而不是字段,则需要注释构造函数参数 - 使用@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)
Run Code Online (Sandbox Code Playgroud)

编辑:实际上,因为注释目标的分辨率顺序是

  • PARAM;
  • 属性;
  • 领域.

根据文档,没有注释目标也应该注释构造函数的参数.所以你可以完全放弃目标:

@Singleton
class SpiceMix @Inject constructor(@Named("oregano") private val oregano: Spice,
                                   @Named("sage") private val sage: Spice,
                                   @Named("rosemary") private val rosemary: Spice)
Run Code Online (Sandbox Code Playgroud)