Is it possible to change Singleton (or any parameter) values after the initial Kodein instantiation?
See original GitHub issueI’d really like to be able to change the value of my HTTP clients baseUrl value, because it can be set dynamically while using the application. I’m having trouble finding a way to change parameter values dynamically.
I’ve looked into Multiton
binding as it seemed like a type of Singleton-Factory that would allow the arguments to be changed. But I had no luck with that.
Here is my Api singleton:
interface LoginApi {
@POST("Account/Login")
@FormUrlEncoded
fun login(
@Field("username") username: String,
@Field("password") password: String,
@Field("sessionType") sessionType: String
): Call<BaseApiResponse<Login>>
@GET("Account/Logout")
fun logout(
@Query("token") token: String
): Call<BaseApiResponse<Any>>
companion object {
operator fun invoke(
baseUrl: String,
cache: Cache
): LoginApi {
val okHttpClient = OkHttpClient.Builder()
.cache(cache)
.readTimeout(60, TimeUnit.SECONDS)
.connectTimeout(60, TimeUnit.SECONDS)
.build()
return Retrofit.Builder()
.client(okHttpClient)
.baseUrl(baseUrl)
.addConverterFactory(JacksonConverterFactory.create())
.build()
.create(LoginApi::class.java)
}
}
}
Dependency Declaration with muliton (doesn’t work):
import(androidXModule(this@MyApplication))
bind<Any>() with multiton { baseUrl: String, applicationContext: Context ->
createLoginApi(baseUrl, applicationContext)
LoginApi(
BuildConfig.BASE_URL,
Cache(applicationContext.cacheDir, 10 * 1024 * 102)
)
}
bind<LoginDataSource>() with singleton { LoginService(instance()) }
bind<LoginRepository>() with singleton { LoginRepositoryImpl(instance()) }
bind() from singleton { LoginViewModelFactory(instance()) }
bind() from singleton { LoginViewModel(instance()) }
}
Dependency Declaration with no multiton (works):
import(androidXModule(this@MyApplication))
bind() from singleton {
LoginApi(
BuildConfig.BASE_URL,
Cache(applicationContext.cacheDir, 10 * 1024 * 102)
)
}
bind<LoginDataSource>() with singleton { LoginService(instance()) }
bind<LoginRepository>() with singleton { LoginRepositoryImpl(instance()) }
bind() from singleton { LoginViewModelFactory(instance()) }
bind() from singleton { LoginViewModel(instance()) }
}
Version
implementation 'org.kodein.di:kodein-di-generic-jvm:6.3.2'
implementation "org.kodein.di:kodein-di-framework-android-x:6.3.2”
Let me know if you need any other information. This is pretty very simple example – I’d just like to be able to change parameter values dynamically. If that isn’t possible, then is there any way that would allow me to do such a thing
Thank you in advance!
Issue Analytics
- State:
- Created 4 years ago
- Comments:10 (4 by maintainers)
Top GitHub Comments
that should work, but you’re code is not entirely decoupled.
When retrieving the instance of
LoginRepository
Kodein will:LoginRepository
LoginRepositoryImpl
waiting for aLoginDataSource
LoginDataSource
binding that need a parameterargs: LoginArguments
LoginService
withargs: LoginArguments
as parameterinstance(arg = LoginArguments(BuildConfig.BASE_URL))
Hope this is clear enough.
Well, I get what you’re trying to do. There is no magic in Kodein, if you bind a
multiton
with some arguments, like:You can’t expect from Kodein to retrieve it with some dynamic values by applying the
instance
function, as you can have multiple instances to inject.What you could do is to use another
multiton
, like:thus, the usage of
LoginDataSource
could be something like: