Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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
like image 702
crgarridos Avatar asked Jan 04 '18 21:01

crgarridos


1 Answers

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
like image 114
BrantApps Avatar answered Nov 02 '22 16:11

BrantApps