Kotlin + Dagger2: cannot be provided without an @Inject constructor or from an @Provides- or @Produces-annotated method

自作多情 提交于 2019-12-07 00:33:24

问题


I'm getting the following error:

Error:(8, 1) error: java.lang.String cannot be provided without an @Inject constructor or from an @Provides- or @Produces-annotated method.

I'm stuck trying to make a module that provides two qualified Strings. Here is the simplified setup of dagger.

@Singleton
@Component(modules = [GreetingsModule::class])
interface AppComponent {
    fun inject(activity: MainActivity)
}

@Qualifier annotation class Spanish
@Qualifier annotation class French
@Qualifier annotation class English

@Module
@Singleton
class GreetingsModule {

    @Provides
    @Spanish
    fun providesHola(): String = "Hola mundo! - From Dagger"

    @Provides
    @English
    fun providesHello(): String = "Hello world! - From Dagger"

}

The injection is done in MainActivity as:

class MainActivity : AppCompatActivity() {

    @Inject @Spanish
    lateinit var holaMundoText: String

    @Inject @English
    lateinit var helloWorldText: String

}

I also tried declaring the getters directly in the component, but it failed with the same error. Same when declaring the module methods as static.

Just as should be, the code works fine with only one @Provide, then the string is injected in both fields. I assume the problem is with the qualifier.

Any help is highly appreciated.


Using:

  • Android Studio 3.0.1
  • Kotlin 1.2.10
  • Dagger 2.14.1

回答1:


There is a bit of a gotcha with qualified and named injection with JSR-330 + Kotlin (Dagger2 is an implementation of this). From recently reviewing the backlog on the Dagger2 project on Github I know the Google team are looking to provide more proactive assistance/more helpful error messages within a forthcoming release (no timescales).

What you are missing is the @field:<Qualifier> annotation use-type targets as described in the linked documentation. So try;

@Inject @field:Spanish lateinit var holaMundoText: String



回答2:


I think the issue is in Kotlin Compiler, it doesn't know place where put such annotation (param, setter, field and so on). To avoid ugly @field:Spanish (Spanish annotation class is tagged with Qualifier annotation) I've found another solution: Just tag Spanish annotation with Target annotation with appropriate params, see example:

@Qualifier
@Target(FUNCTION, CONSTRUCTOR, FIELD, VALUE_PARAMETER, PROPERTY_SETTER)
annotation class Spanish

then you can use:

@Inject @Spanish
lateinit var holaMundoText: String


来源:https://stackoverflow.com/questions/48103894/kotlin-dagger2-cannot-be-provided-without-an-inject-constructor-or-from-an

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!