Вставка конструктора Dagger 2 в kotlin с именованными аргументами

У меня есть эта зависимость:

@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

Вы хотите аннотировать параметры конструктора, если вы выполняете инъекцию конструктора, а не поля - используйте @param: annotation:

@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)

Изменение: на самом деле, поскольку порядок разрешения для целей аннотации

  • пары;
  • имущество;
  • поле.

согласно документам, отсутствие цели аннотации также должно аннотировать параметр конструктора. Таким образом, вы можете просто полностью удалить цель:

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