I have Koin in my project, and I instantiate retro...
# koin
p
I have Koin in my project, and I instantiate retrofit like this in the appmodule:
Copy code
single<ApiService> {
    Retrofit.Builder()
        .baseUrl("<https://myurl.es>")
        .addConverterFactory(JacksonConverterFactory.create())
        .addConverterFactory(ScalarsConverterFactory.create())
        .build()
        .create(ApiService::class.java)
}
The issue is that I need to parametrize the baseUrl to retrofit, because the user can change it with a textfield. How can I tell Koin that must initialize this singleton for retrofit with a dinamically passed variable? I only found very complex samples for doing this using factory instead of singleton, and doing it with field injection instead of constructor injection, so I hope there is a simpler way.
w
The concept of singleton and also a parameterized dependency are not compatible. You want a factory
☝️ 3
p
But I need that ApiService to be a singleton, to be a single instance injected in all the project
and also, to be able to inject it on constructors
not just in fields
w
I suggest using
factory
and the
retrofit.newBuilder()
api. Keep your retrofit as a singleton, then in your Api definition use a factory where you can pass the base url
p
what do you mean with keep your retrofit as a singleton? also, I'm not sure I understand your last sentence, maybe a sample whould help
w
Investigate the Retrofit API, look for ways to solve “How do I change the URL of a Retrofit instance?” Think about how you could utilize the same retrofit instance over and over while changing it’s URL
c
Why don't you just use interceptor in okhttp to dynamically set URL, this way you can still keep everything as Singleton https://bbasoglu.medium.com/part-1-how-to-change-base-url-on-runtime-in-an-android-project-1d7607bbfa48
p
are you sure that trick works? seems to be a little hack, also, not sure about the efficiency of that, seems to be building the connection each time? and how can I rebuilt it only if the interceptor has changed? even more, how can It detects has changed to rebuilt it?
w
Probably the better option here is to rethink your flow/UX. Alternatively you can load/unload your api koin module whenever the user changes the URL
Or just accept that you’re not going to have Singleton instances of your Api class. You can have singletons for your OkHttpClient and your Retrofit instance, and then a factory for your Api
c
Another way I could think of is using StateFlow, but that is too complicated. About the interceptor way, I have one implemented at https://github.com/CXwudi/realworld-compose-http4k-example-app/blob/master/conduit-frontend/frontend-decompose-logic/src/commonMain/kotlin/mikufan/cx/conduit/frontend/logic/repo/api/setup.kt. I was using ktorfit and ktor. Ktor registered a plugin that does the URL setup, as well as token setup. I am not sure if this implementation makes sense to you, but at least it works well for me