Reputation: 498
@Module
@InstallIn(SingletonComponent::class)
object NetworkModule {
@Singleton
@Provides
fun provideRetrofit(okHttpClient: OkHttpClient): Retrofit {
return Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl("http://example.com/")
.client(okHttpClient)
.build()
}
@Singleton
@Provides
fun provideMyRetrofit(okHttpClient: OkHttpClient): Retrofit {
return Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl("http:/my.com/")
.client(okHttpClient)
.build()
}
}
Their difference is only baseUrl
.
I tried to solve this problem by use @Qualifier
.
interface RetrofitQualifier {
@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class Retrofit
@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class MyRetrofit
}
@Module
@InstallIn(SingletonComponent::class)
object NetworkModule {
@Singleton
@Provides
@RetrofitQualifier.Retrofit
fun provideRetrofit(okHttpClient: OkHttpClient): Retrofit {
return Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl("http://example.com/")
.client(okHttpClient)
.build()
}
@Singleton
@Provides
@RetrofitQualifier.MyRetrofit
fun provideMyRetrofit(okHttpClient: OkHttpClient): Retrofit {
return Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl("http:/my.com/")
.client(okHttpClient)
.build()
}
}
And I use it by use @RetrofitQualifier.MyRetrofit
in my class:
class MyRepository @Inject constructor(
application: Application
) {
...
@Inject
@RetrofitQualifier.MyRetrofit
lateinit var retrofit:Retrofit
private val service: Service = retrofit.create(Service::class.java)
...
}
However, I was failed, the log is
kotlin.UninitializedPropertyAccessException: lateinit property retrofit has not been initialized
What should I do? Maybe use @Named
? I am not sure...
Upvotes: 12
Views: 6278
Reputation: 20626
Example with Qualifier
, you can add this in the same file where you have your providers or even create a RetrofitQualifier.kt
file and add them there.
@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class RetrofitOne
@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class RetrofitTwo
And the @Provides
@Singleton
@Provides
@RetrofitOne
fun provideRetrofit(okHttpClient: OkHttpClient): Retrofit {
return Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl("http://example.com/")
.client(okHttpClient)
.build()
}
@Singleton
@Provides
@RetrofitTwo
fun provideMyRetrofit(okHttpClient: OkHttpClient): Retrofit {
return Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl("http:/my.com/")
.client(okHttpClient)
.build()
}
Then in your Repository
you can inject using two options
Field injection
// At field injection.
@AndroidEntryPoint
class MyRepository @Inject constructor(...) {
@RetrofitOne
@Inject lateinit var retrofit: Retrofit
}
As a dependency injected-constructor class
// As a dependency of a constructor-injected class.
class MyRepository @Inject constructor(
@RetrofitTwo private val retrofit: Retrofit
) : ...
But the thing is that perhaps you installedIn in another module where your Repository doesn't have visibility.
About the @Named
you can still use it but as per the documentation is recommended to use Qualifier
Upvotes: 27