代码之家  ›  专栏  ›  技术社区  ›  Vas

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

  •  30
  • Vas  · 技术社区  · 7 年前

    我有这种依赖性:

    @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
    

    我认为@命名注释在我的构造函数签名中不太起作用。我不太确定我怎样才能使它起作用。

    注意:如果我放弃命名注释并将构造函数参数的类型更改为它们的具体形式,那么这可以很好地编译。然而,Spice是一个接口,我在测试中需要它来模拟。

    我能做什么?

    1 回复  |  直到 6 年前
        1
  •  43
  •   zsmb13    7 年前

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