I have a function that returns an API, which needs an OkHttpClient instance
@Module
@InstallIn(ApplicationComponent::class)
object AuthNetworkModule {
@Provides
fun provideAuthRetrofitService (@AuthQualifier okHttpClient: OkHttpClient): IQuipsAuth{
return Retrofit.Builder()
.baseUrl("${Config.BASE_URL}/")
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create(GsonBuilder().setLenient().create()))
.build().create(IQuipsAuth::class.java)
}
And I also have a function that returns an OkHttpClient that needs an API instance for the authenticator, what do I do?
@Provides
@AuthQualifier
fun provideOkHttpClient (application: Application, iQuipsAuth: IQuipsAuth): OkHttpClient {
val interceptor = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger {
override fun log(message: String) {
Log.d("HttpLoggingInterceptor", message)
}
}).setLevel(HttpLoggingInterceptor.Level.HEADERS)
return OkHttpClient.Builder()
.readTimeout(180, TimeUnit.SECONDS)
.writeTimeout(45, TimeUnit.SECONDS)
.hostnameVerifier { _: String?, _: SSLSession? -> true }
.addInterceptor(interceptor)
.addInterceptor(AccessTokenInterceptor(application, iQuipsAuth))
.authenticator(AccessTokenAuthenticator(application, iQuipsAuth))
.build()
}
}
I am trying to recreate this same Koin code in Hilt:
single {
val interceptor = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger {
override fun log(message: String) {
Log.d("HttpLoggingInterceptor", message)
}
}).setLevel(HttpLoggingInterceptor.Level.BODY)
val okHttpClient = OkHttpClient.Builder()
.readTimeout(180, TimeUnit.SECONDS)
.writeTimeout(45, TimeUnit.SECONDS)
.hostnameVerifier { _: String?, _: SSLSession? -> true }
.addInterceptor(interceptor)
.build()
val retrofit = Retrofit.Builder()
.baseUrl("${Config.baseUrl}/")
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create(get()))
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build()
retrofit.create(IQuipsAuth::class.java)
}
You can workaround dependency cycles using dagger.Lazy<T>
.
fun provideOkHttpClient (application: Application, iQuipsAuth: Lazy<IQuipsAuth>): OkHttpClient {
// ...
.addInterceptor(AccessTokenInterceptor(application, iQuipsAuth)) // pass lazy
.authenticator(AccessTokenAuthenticator(application, iQuipsAuth)) // pass lazy
// ...
}
Then invoke lazy.get()
when the client is actually used.
Please note that this would be more self-evident if the AccessTokenInterceptor
and AccessTokenAuthenticator
were both provided to Dagger using @Inject constructor
, and provided to this @Provides
method as arguments of the method.