Koin: Dynamic parameter injection

Created on 21 Feb 2018  路  6Comments  路  Source: InsertKoinIO/koin

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.

Most helpful comment

Hi there! How is it going in 2.0?

All 6 comments

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

Was this page helpful?
0 / 5 - 0 ratings

Related issues

iRYO400 picture iRYO400  路  3Comments

haroldadmin picture haroldadmin  路  3Comments

TedHoryczun picture TedHoryczun  路  4Comments

hkelidari picture hkelidari  路  3Comments

dakuenjery picture dakuenjery  路  4Comments