How can I inject the same CoroutineScope in two cl...
# koin
l
How can I inject the same CoroutineScope in two classes, e.g. a ViewModel and a Repository? Is it enough to just create a named CoroutineScope instance and inject it in both?
a
Why do you want to handle Coroutines with Koin? 🤔
l
I have a ViewModel that depends on Repository. The repository collects a
StateFlow
from another dependency (DataSource). But I need a new instance of Repository for every ViewModel. So I want to use the same
CoroutineScope
in the ViewModel and in the Repository, so that the scope is automatically canceled when ViewModel is cleared.
So I was thinking: 1. Create a
CoroutineScope
instance 2. Inject it into Repository 3. Inject it into ViewModel
a
Ok. don’t remember if you can achieve this just with Coroutines API 🤔 I mean continuing from the caller scope
l
I need to start collecting one StateFlow in the Repository, which will update some internal state of the Repository. The Repository will then expose another StateFlow (with its own state) which the viewmodel will collect. But I want the collection both in the Repository and in the ViewModel to be canceled when the ViewModel is cleared.
There is no connection from the ViewModel to the Repository collection of its dependency's StateFlow. The only way to share the scope is to have the same instance and inject it.
It's probably hard to follow, sorry for this convoluted description. But I don't have right now a good example code. I'm testing my concept right now.
j
single { MyScope() } viewModel { SomeViewModel(get()) } factory { SomeRepository(get()) }
Anyway I don't see why you need that scope, when the VM is cleared the factory repository is not going to be reused when the viewmodel is created again, if you use factory instead of single
l
I need to cancel the coroutines which the repository started (collecting hot flow)
j
Are you sure that the coroutine is still running when the repository is destroyed after the vm is cleared even if you are not sharing the scope?
l
The repository is not "destroyed"
What would it mean?
The coroutine is running in the background and keeps a reference to the repository which started it
That's how memory leaks are created.
j
If the repository is injected in the viewmodel and the viewmodel is destroyed, the repository is destroyed too
l
What does it mean "destroyed" in the JVM?
There is no "destructor". There is one in C++, but not on the JVM
Repository is just a class. If I don't write a cleanup method, then there will be no cleanup of started coroutines, open resources. They will start leaking.
j
I think you can achieve the same behavior without using a stateflow in the repository
normal flow + distinct and you can transform it later to stateflow in the vm if it was necessary
anyway you can get the job from the repository to cancel the flow too
Copy code
val job = scope.launch { flow.cancellable().collect { } }
job.cancel()
you can return that job from the repository and cancel it in the vm
l
Thanks for your remarks.
176 Views