I have a simple class as below
class MainString(val msg: String)
I want to inject with different argument to it, so I use the @Named
Qualifier as per the guide shown in https://google.github.io/dagger/users-guide
With that my AppModule has
@Provides @Named("Two")
fun provideTwoMainString(): MainString {
return MainString("Two")
}
@Provides @Named("One")
fun provideOneMainString(): MainString {
return MainString("One")
}
And in my MainActivity, I just call
@Inject @Named("One")
lateinit var stringOne: MainString
@Inject @Named("Two")
lateinit var stringTwo: MainString
However, when I compile, it complains
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.
It seems to want me to provide another Provider without the qualifier. So if I add the below, all will compiles. But it is not of used to me, as I want to have different argument injection.
@Provides
fun provideMainString(): MainString {
return MainString("Solo")
}
What have I done wrong?
Annotation work slightly different on kotlin. look this doc
You have to annotate the field as:
@Inject @field:Named("Two")
lateinit var stringOne: MainString
If you add the following to your qualifier annotation:
@Target(FIELD, VALUE_PARAMETER, FUNCTION, PROPERTY_GETTER, PROPERTY_SETTER)
then you won't have to add "field:"
For example, with:
@Qualifier
@Retention(RUNTIME)
@Target(FIELD, VALUE_PARAMETER, FUNCTION, PROPERTY_GETTER, PROPERTY_SETTER)
annotation class One
you can inject as follows:
@Inject @One lateinit var stringOne: String
Unfortunately @Named
doesn't specify the @Target(..)
, so just create your own annotations. @Named
is a bad idea anyway, since it's using string literals.
1) If you are using a qualifier like following, here 'OmdbService'
@Qualifier
public annotation class OmdbService
Then use
@Inject @field:OmdbService lateinit var retrofitOmdbService: Retrofit
2) If are using a named provider like following, here '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()
}
Then use
@Inject @field:Named("orangeservice_retrofit") lateinit var retrofitOrangeService: Retrofit