I am using Koin as a DI for my app. I created a module:
object NetworkModule {
fun get() = module {
single {
val authenticationInterceptor = Interceptor { chain ->
// Request customization goes here
}
OkHttpClient.Builder()
.connectTimeout(15, TimeUnit.SECONDS)
.readTimeout(60, TimeUnit.SECONDS)
.writeTimeout(60, TimeUnit.SECONDS)
.addInterceptor(authenticationInterceptor) //Not all clients might have this interceptor
.build()
}
single {
Retrofit.Builder()
.baseUrl("example.com")
.client(get(/* I would like to send some paramter here */))
.addConverterFactory(GsonConverterFactory.create(get()))
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build()
.create(Api::class.java)
}
}
}
How can I create different HttpClient
or Retrofit
instances which have different parameters set or has different instantiation? For instance, in some cases, I might need OkHttpClient
with AutheniticationInterceptor
and in some other cases my client might not need to use it.
Can I pass some parameters when calling get()
so that I can get different instances? Any suggestions would be apprieciated.
This article has covered dependency injection and how to use Koin, a Kotlin dependency injection framework, to handle dependencies. Koin has shown to be simple to set up and use.
Koin works without any use of proxies, code generation or reflection. This makes it as usable in Android Apps and Ktor Microservices as standard Java programs.
Koin is a dependency injection framework for Kotlin. It is lightweight, can be used in Android applications, is implemented via a concise DSL, and takes advantage of Kotlin features like delegate properties rather than relying on annotations.
Koin is a smart Kotlin dependency injection library to keep you focused on your app, not on your tools. Koin gives you simple tools and API to let you build, assemble Kotlin related technologies into your application and let you scale your business with easyness. Define Modules. Start Koin. Start on Android.
You can use named properties - e.g.
single<OkHttpClient>(named("auth")){
// here you pass the version with authinterceptor
}
single<OkHttpClient>(named("noAuth")){
// here you pass the version without authinterceptor
}
Then in your get() method you pass the name, e.g.
.client(get(named("auth")))
You can do like below (Use koin latest version for named property).Also why I use single and factory because
single— declare a singleton definition of given type. Koin keeps only one instance of this definition
factory — declare a factory definition of given type. Koin gives a new instance each time
const val WITH_AUTH: String = "WITH_AUTH"
const val WITH_OUT_AUTH: String = "WITH_OUT_AUTH"
val remoteModule = module {
factory(named("HEADERS")) {
val map = it.get<MutableMap<String, String>>(0)
Interceptor { chain ->
val original = chain.request()
val request = original.newBuilder()
map.forEach { entry ->
request.addHeader(entry.key, entry.value)
}
chain.proceed(request.build())
}
}
factory(named("auth")) {
OkHttpClient.Builder().apply {
map["AUTHORIZATION"] = "token"
readTimeout(1, TimeUnit.MINUTES)
connectTimeout(2, TimeUnit.MINUTES)
writeTimeout(1, TimeUnit.MINUTES)
addInterceptor(get(named("HEADERS"), parameters = {
parametersOf(map)
}))
}.build()
}
factory(named("auth")) {
Retrofit.Builder()
.baseUrl("base_url")
.client(get(named("auth")))
//.addCallAdapterFactory()
.addConverterFactory(GsonConverterFactory.create())
.build()
.create(ApiService::class.java)
}
single(named("noAuth")) {
val map = mutableMapOf(ACCEPT to CONTENT_TYPE)
OkHttpClient.Builder().apply {
readTimeout(1, TimeUnit.MINUTES)
connectTimeout(2, TimeUnit.MINUTES)
writeTimeout(1, TimeUnit.MINUTES)
addInterceptor(get(named("HEADERS"), parameters = {
parametersOf(map)
}))
}.build()
}
single(named("noAuth")) {
Retrofit.Builder()
.baseUrl("base_url")
.client(get(named("noAuth")))
//.addCallAdapterFactory()
.addConverterFactory(GsonConverterFactory.create())
.build()
.create(ApiService::class.java)
}
}
Now in your activity or viewModel
protected val apiServiceWithoutHeader: ApiService by inject(named(WITH_OUT_HEADER))
protected val apiServiceWithHeader: ApiService by inject(named(WITH_HEADER))
with above object call appropriate API
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With