Skip to content
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

Dynamic parameter injection #59

Closed
aouerf opened this issue Feb 21, 2018 · 6 comments
Closed

Dynamic parameter injection #59

aouerf opened this issue Feb 21, 2018 · 6 comments
Milestone

Comments

@aouerf
Copy link

aouerf commented Feb 21, 2018

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.

@arnaudgiuliani
Copy link
Member

arnaudgiuliani commented Feb 21, 2018

Hello,

factory bindings are interesting and remind me the Android see injector from dagger (#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.

@aouerf
Copy link
Author

aouerf commented Feb 22, 2018

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?

@arnaudgiuliani arnaudgiuliani added this to the 0.9.0 milestone Feb 22, 2018
@arnaudgiuliani
Copy link
Member

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👍

@pablobaldez
Copy link

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) 
}

@iRYO400
Copy link

iRYO400 commented Oct 28, 2019

Hi there! How is it going in 2.0?

@ZaydelEduard
Copy link

@iRYO400 Look here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants