I'm using the koin-android-architecture version of the library. I've come across a situation where I'd like to use a parameter determined when an Activity/Fragment is created for a ViewModel. As an example:
SomeActivity.kt
class SomeActivity : BaseActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val id = getIdExtra() // From intent
TODO("use id")
val viewModel = getViewModel<SomeViewModel>()
// ...
}
}
SomeViewModel.kt
class SomeViewModel(
private val repository: Repository, // Singleton
private val id: Long
) : BaseViewModel() {
// ...
}
Is there a good way of doing this? I know that Kodein has factory bindings, so I was wondering if there was something similar.
This issue is similar to #6 but I was wondering if there was a better method of achieving this now since that issue is relatively old.
Hello,
factory bindings are interesting and remind me the Android see injector from dagger (https://github.com/Ekito/koin/issues/49)
In the current version, you can use setProperty() to set a property that can be used later in injection:
class SomeActivity : BaseActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val id = getIdExtra() // From intent
setProperty("id",id)
val viewModel = getViewModel<SomeViewModel>()
// ...
}
}
with class
class SomeViewModel(
private val repository: Repository, // Singleton
private val id: Long
) : ViewModel()
you have to write your module entry with getProperty:
val module = applicationContext {
bean { SomeViewModel(get(), getProperty("id")) }
}
I'm actually thinking about something like kodein factory bindings.
Yeah that's what I went with, although I still think that dynamic factory bindings would be nice. Out of curiosity, if you're considering adding them, do you have an idea of how it would look like?
I 've add Koin parameters to release 0.9.0.
you will be able to use parameters in your definition. Given class:
class MyPresenter(val activity : MyActivity)
We can use parameters to be injected with by inject()
val module = applicationContext {
factory { params -> MyPresenter(params["activity"])}
}
Injecting the parameter:
class MyActivity : AppCompatActivity(){
// Ask for MyPresenter injection and provide parameters
val presenter : MyPresenter by inject( parameters = mapOf("activity" to this))
}
stay tuned馃憤
It's a good aproach provides an activity instance in factory method using the getProperty method? Or could it give me some memory leaks?
Example code:
factory { getProperty("activity") }
factory {
// here we get the activity instance provided previously to make the factory of some another instance
val activity = get<Activity>()
LocalBroadcastManager.getInstance(activity)
}
Hi there! How is it going in 2.0?
@iRYO400 Look here
Most helpful comment
Hi there! How is it going in 2.0?