【问题标题】:Dagger2 Qualifier not working with Kotlin?Dagger2 Qualifier 不适用于 Kotlin?
【发布时间】:2018-07-11 21:45:30
【问题描述】:

我有一个简单的类如下

class MainString(val msg: String)

我想为它注入不同的参数,所以我按照https://google.github.io/dagger/users-guide 中显示的指南使用@Named 限定符

我的 AppModule 有了

@Provides @Named("Two")
fun provideTwoMainString(): MainString {
    return MainString("Two")
}

@Provides @Named("One")
fun provideOneMainString(): MainString {
    return MainString("One")
}

在我的 MainActivity 中,我只是调用

@Inject @Named("One")
lateinit var stringOne: MainString

@Inject @Named("Two")
lateinit var stringTwo: MainString

但是,当我编译时,它会抱怨

Error:(11, 1) error: com.elyeproj.demo_dagger_scope.MainString cannot be provided without an @Inject constructor or from an @Provides- or @Produces-annotated method.

似乎希望我提供另一个没有限定符的 Provider。因此,如果我添加以下内容,所有内容都会编译。但我不习惯,因为我想要不同的参数注入。

@Provides
fun provideMainString(): MainString {
    return MainString("Solo")
}

我做错了什么?

【问题讨论】:

    标签: android kotlin dagger-2


    【解决方案1】:

    注释在 kotlin 上的工作略有不同。看this doc

    您必须将字段注释为:

    @Inject @field:Named("Two")
    lateinit var stringOne: MainString
    

    【讨论】:

      【解决方案2】:

      如果您将以下内容添加到限定符注释中:

      @Target(FIELD, VALUE_PARAMETER, FUNCTION, PROPERTY_GETTER, PROPERTY_SETTER)
      

      那么您就不必添加“字段:”

      例如,用:

        @Qualifier
        @Retention(RUNTIME)
        @Target(FIELD, VALUE_PARAMETER, FUNCTION, PROPERTY_GETTER, PROPERTY_SETTER)
        annotation class One
      

      你可以按如下方式注入:

        @Inject @One lateinit var stringOne: String
      

      很遗憾@Named 没有指定@Target(..),所以只需创建自己的注释即可。 @Named 无论如何都是个坏主意,因为它使用的是字符串文字。

      【讨论】:

        【解决方案3】:

        1) 如果您使用如下限定符,此处为“OmdbService”

        @Qualifier
        public annotation class OmdbService
        

        然后使用

        @Inject  @field:OmdbService lateinit var retrofitOmdbService: Retrofit
        

        2) 如果使用如下命名的提供者,这里是 'orangeservice_retrofit'

        @Provides
            @OrangeApplicationScope
            @Named("orangeservice_retrofit")
            fun retrofit(okHttpClient :OkHttpClient, gson : Gson, c :Context): Retrofit {
                return Retrofit.Builder()
                        .addConverterFactory(GsonConverterFactory.create(gson))
                        .client(okHttpClient)
                        .baseUrl(c.getString(R.string.base_url))
                        .build()
        }
        

        然后使用

        @Inject @field:Named("orangeservice_retrofit") lateinit var retrofitOrangeService: Retrofit
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2017-05-15
          • 1970-01-01
          • 1970-01-01
          • 2015-07-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多