@Qualifier 原因:[Dagger/MissingBinding] 字段注入时

@Qualifier causes: [Dagger/MissingBinding] when field injecting

我遇到了这个问题:

ApplicationComponent.java:8: error: [Dagger/MissingBinding] @... java.text.SimpleDateFormat cannot be provided without an @Provides-annotated method.

模块

@Module
abstract class ApplicationModule {

    @Binds
    @AppContext
    abstract fun application(app: App): Context

    @Module
    companion object {
        ...

        @Provides
        @Singleton
        @CalendarPickerDateFormat
        fun provideCalendarPickerDateFormat(): SimpleDateFormat {
            return SimpleDateFormat("dd/MMM/yyyy", Locale.getDefault())
        }
    }
}

限定词

@Qualifier
@Retention(AnnotationRetention.RUNTIME)
annotation class CalendarPickerDateFormat

Class

@ActivityScope
class MyClass
@Inject constructor(
   ...,
    @CalendarPickerDateFormat private val calendarDateFormat: SimpleDateFormat
) {...}

即使我将 @Target(AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY) 添加到 Qualifier 并将 class 构造函数更改为 @param:CalendarPickerDateFormat,我也会得到相同的错误。

缺少什么?

可能的解决方案

添加@JvmStatic喜欢:

@Provides
@Singleton
@JvmStatic
@CalendarPickerDateFormat
fun provideCalendarPickerDateFormat(): SimpleDateFormat {
      return SimpleDateFormat("dd/MMM/yyyy", Locale.getDefault())
}

解决构造函数注入但不解决字段注入:

@Inject
@CalendarPickerDateFormat lateinit var date : SimpleDateFormat

为什么?

注意:我也尝试了 @Module object class approach,但结果相同。

我已经在 google/Daggers repo and this PR 中打开了一个问题 "fix"。实际上,这不是错误,正如 zsmb13 提到的:

From the official Kotlin docs:

If you don't specify a use-site target, the target is chosen according to the @Target annotation of the annotation being used. If

there are multiple applicable targets, the first applicable target from the following list is used:

    param;
    property;
    field.

So basically, it's because param is the default target when it's not specified.

但是这个 PR 将非常有助于避免将来出现这种情况。

编辑Dagger 2.25.2 fixes it.