I would be also interested in sharing the same Vie...
# koin
l
I would be also interested in sharing the same ViewModel instance between a composable (or multiple composables) and host Fragment/Activity. My use case is that I have click callbacks in the composables which trigger events in the viewmodel. Then host Fragment subscribes to this event to show snackbar or trigger navigation.
m
You could create a custom Scope and pass in a "session" object so that each view model gets the same instance
l
But then every time I navigate away I would have to destroy the scope.
m
The scope can be given to each view model
l
Yes, but I want to have a new viewmodel once I navigate to the same screen with new data
m
That would mean you create a new "session".
eg if you have screens like A -> B -> C you would create a new shard "session" object when starting A and pass that shared object to B and C
l
So then I would need to create/destroy the session as part of my navigation, right?
m
Actually not as part of the navigation but automatically in your koin module declaration
l
So I just have to do
getKoin().createScope()
? But when will the session be finished? Will it be automatically finished when I leave the starting fragment?
m
In that case that would be up to the screen/ViewModel that the session is tied to
Example:
l
Ok, that sounds like a good idea to try out.
m
you create a module with a Session
Copy code
private val myModule = module {
        scope<Session> {
            scoped { MySession() }
        }
    }
and another which would create your ViewModels:
Copy code
private var mySessionScope: Scope? = null
    private val viewModelModule = module {
        viewModel {
            mySessionScope = getKoin().createScope<Session>()
            with(requireNotNull(mySessionScope)) {
                ScreenAViewModel(get(), get()).apply {
                    addCloseable { close() }
                }
            }
        }
        viewModel {
            with(requireNotNull(mySessionScope)) {
                ScreenBViewModel(get())
            }
        }
        viewModel {
            with(requireNotNull(mySessionScope)) {
                ScreenCViewModel(get())
            }
        }
    }
Here you can saee that ScreenA is used to close the mySessionScope scope
the
get()
calls would be able to resolve the shared
MySession
.
l
Interesting, I didn't see that
addCloseable
before...
m
That is from androidx.lifecycle.ViewModel
it would than be able to close the session
The solution is not 100% nice because the sessionScope is held in a separate var instead of getting from the koin object each time.
l
I see, that's new in 2.5.0
Thanks for your suggestions, do you know any resource/article which goes in more depth into scoped viewmodels in Koin? I find that the documentation is missing some of the more specific use cases.
m
yeah i agree. i pieced it together from the docs and various repos i think.
no immediate pointers
l
Ok, thanks so much for your help, this is really cool!
m
you are welcome. Good Luck.
135 Views