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

时间:2018-01-25 12:14:01

标签: 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) 

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

@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注释在我的构造函数签名中不起作用。我不太确定如何才能使它发挥作用。

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

我该怎么办?

1 个答案:

答案 0 :(得分:23)

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

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

  
      
  • PARAM;
  •   
  • 属性;
  •   
  • 字段。
  •   

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

@Singleton
class SpiceMix @Inject constructor(@Named("oregano") private val oregano: Spice,
                                   @Named("sage") private val sage: Spice,
                                   @Named("rosemary") private val rosemary: Spice)