-
Notifications
You must be signed in to change notification settings - Fork 174
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Is it possible to change Singleton (or any parameter) values after the initial Kodein instantiation? #247
Comments
Hello, We don't recommend to change the kodein instance at runtime. In fact, it's not possible out of the box. You are on the right tracks, You need to bind Be careful, in 6.5 we will depreciate mutli arguments factories/multiton, we recommend to use data class LoginArguments(val baseUrl: String, val applicationContext: Context)
bind<LoginApi>() with multiton { args: LoginArguments ->
createLoginApi(args.baseUrl, args.applicationContext)
LoginApi(
BuildConfig.BASE_URL,
Cache(args.applicationContext.cacheDir, 10 * 1024 * 102)
)
} tell me if that helps. |
Thanks for the reply Here’s the new bind<LoginApi>() with multiton { baseUrl: String, applicationContext: Context ->
createLoginApi(baseUrl, applicationContext)
LoginApi(
baseUrl,
Cache(applicationContext.cacheDir, 10 * 1024 * 102)
)
} createLoginApi() function: (pretty much same thing in private fun createLoginApi(baseUrl: String, applicationContext: Context) =
LoginApi(
baseUrl,
Cache(applicationContext.cacheDir, 10 * 1024 * 102)
) Error when using Multiton:
Let me know if you need any other information - I haven’t changed anything else. Also:
This sound very nice! Looking forward! |
You can now use a data class, no need to wait until 6.5. In 6.5 the ability to use mutliple argument in multiton will be deprecated. So you must in data class from now. How do you try to inject your multiton ? |
Alright so i just changed to use the Multiton w/ data class bind<LoginApi>() with multiton { args: LoginArguments ->
createLoginApi(args.baseUrl, applicationContext)
LoginApi(
args.baseUrl,
Cache(applicationContext.cacheDir, 10 * 1024 * 102)
)
}
// The Datasource is then bound with the LoginApi supplied using the `instance()` function
bind<LoginDataSource>() with singleton { LoginService(instance()) }
Error (see comment I included in StackTrace):
Well I guess it’s injected via the When it comes to retrieving the dependencies (i.e. |
I’m doing everything you previously suggested in a similar issue: #178 (comment) |
Well, I get what you're trying to do. bind<LoginApi>() with multiton { args: LoginArguments -> ... } You can't expect from Kodein to retrieve it with some dynamic values by applying the What you could do is to use another bind<LoginDataSource>() with multiton { args: LoginArguments -> LoginService(instance(arg = args)) } thus, the usage of val dataSource: LoginDataSource by kodein.instance(arg = LoginArguments("/path", context)) |
Thanks for all the quick replies. (If you haven’t noticed) DI is all new to me... I’m curious how I would use the Here is my current override val kodein = Kodein.lazy {
// must import Application class. NOTE: must use `androidXModule` - we're using AndroidX.
import(androidXModule(this@Application))
registerContextTranslator { f: Fragment -> f.activity }
bind<LoginApi>() with multiton { args: LoginArguments ->
createLoginApi(args.baseUrl, applicationContext)
LoginApi(
args.baseUrl,
Cache(applicationContext.cacheDir, 10 * 1024 * 102)
)
}
// bind<LoginDataSource>() with singleton { LoginService(instance()) }
bind<LoginDataSource>() with multiton { args: LoginArguments -> LoginService(instance(arg = args)) }
bind<LoginRepository>() with singleton { LoginRepositoryImpl(instance()) }
bind() from singleton { LoginViewModelFactory(instance()) }
bind() from singleton { LoginViewModel(instance()) }
} LoginFragment class LoginFragment : Fragment(R.layout.fragment_login), KodeinAware {
override val kodein by closestKodein()
val viewModel: LoginViewModel by lazy { on(requireActivity()).direct.instance<LoginViewModel>() }
... I’m curious where this: Thanks again |
Ok i think understand after messing around a bit and have it working with the Here’s what I’ve changed in the Kodein declaration block: bind<LoginApi>() with multiton { args: LoginArguments ->
createLoginApi(args.baseUrl, applicationContext)
LoginApi(
args.baseUrl,
Cache(applicationContext.cacheDir, 10 * 1024 * 102)
)
}
bind<LoginDataSource>() with multiton { args: LoginArguments -> LoginService(instance(arg = args)) }
val loginDataSource: LoginDataSource by instance(arg = LoginArguments(BuildConfig.BASE_URL))
// Supply the multiton loginDataSource
bind<LoginRepository>() with singleton { LoginRepositoryImpl(loginDataSource) } Thank you! |
that should work, but you're code is not entirely decoupled. bind<LoginApi>() with multiton { args: LoginArguments ->
createLoginApi(args.baseUrl, applicationContext)
LoginApi(
args.baseUrl,
Cache(applicationContext.cacheDir, 10 * 1024 * 102)
)
}
bind<LoginDataSource>() with multiton { args: LoginArguments -> LoginService(instance(arg = args)) }
bind<LoginRepository>() with singleton {
LoginRepositoryImpl(instance(arg = LoginArguments(BuildConfig.BASE_URL)))
} When retrieving the instance of
Hope this is clear enough. |
Again thanks for all the help. Really appreciate.
How could I decouple this any further...? If you have time to help. Thank you! UPDATE: Update 2: Yes, thank you very much. :) |
I’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:
Dependency Declaration with muliton (doesn’t work):
Dependency Declaration with no multiton (works):
Version
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!
The text was updated successfully, but these errors were encountered: