:android-wave: I am migrating a project from dagge...
# koin
p
👋 I am migrating a project from dagger Hilt to koin (preparations for KMP) and I have troubles with equivalent of
@ViewModelScoped
that we use in few places. My usecase is as follows: I have a viewmodel and 2 usecases. These usecases are using (injecting) the same component. I dagger hilt I have these usecases and component with annotation
@ViewModelScoped
, so even if usecase2 was created, the component class was not recreated. I am trying to achive the same thing in koin, but so far no luck. More detailed schema: class MyViewModel(private val usecase1, private val usecase2): ViewModel() class UseCase1(private val myComponent) class UseCase2(private val myComponent) I tried with
factory
on usecases and component, but then the component is created twice I tried with
single
on usecases and component, but then the component is created once in app lifecycle I tried to make custom scope in compose that use this viewmodel, but I got error with
Check your definitions
. Koin do not see my usecases 😞 What is the proper way to handle it? Please help. I need this migration to start with KMP K
a
from where do you inject
myComponent
?
p
I am using annotations and
myComponent
has Factory annotation. Here is the generated module:
Copy code
scope(org.koin.core.qualifier.StringQualifier("myScope")) {

		scoped() { MyComponent(get(),get(),get()) } 
		scoped() { UseCaseOne(get()) }
		scoped() { UseCaseTwo(get()) } 
	}
    viewModel { MyViewModel(get(), get()) }
this generated module is representing the case where “myScope” is created in compose:
Copy code
val viewModel = koinViewModel<MyViewModel>(
            scope = getKoin().createScope(
                "myScope",
                named("myScope")
            )
        )
and the usecases have the following annotations:
Copy code
@Scope(name = "myScope")
@Scoped
class UseCaseOne (private val myComponent)
the myComponent also is scoped the same way:
Copy code
@Scope(name = "myScope")
@Scoped
class MyComponent()
the ViewModel do not have the
scope
annotation, just
@KoinViewModel
a
depending of what you want to achieve: • resolve objects from ViewModel's scope • resolve objects from a given scope, for ViewModel
p
can you give me an example? I do not understand 🙂
a
1st, you create your ViewModel and then we create its scope, and then we resolve things
2nd you create a scope, and link your ViewModel to it ... but this scope is not tied to your ViewModel
in your case, I imagine more something were you need to maintain MyViewModel MyComponent UseCaseOne & UseCaseTwo together
as long as the VM is living
right?
p
yes
I tried that by adding scope to my viewmodel:
Copy code
@Scope(MyViewModel::class)
@KoinViewModel
class MyViewModel
but in this setup I got error:
Check your definitions
for MyViewModel, which was weird. The generated module looks like that:
Copy code
scope(MyViewModel) {
        viewModel { MyViewModel(get(), get()) }
		scoped() { MyComponent(get(),get(),get()) } 
		scoped() { UseCaseOne(get()) }
		scoped() { UseCaseTwo(get()) } 
	}
I guess the viewmodel cannot be also a scope?
a
the thing is your resolve dependency from Scope into VM ... where effectively you can't make it the scope source if t's resolving deps 🤔
let me double check for the smart way to go here
👍 1
c
nice @Piotr Prus im doing the same thing (converting to koin from hilt in preparation for kmp). let me know how it goes 😅
p
I made one project 2y ago and gradle config was a pain. This part did not change. The koin migration using annotations was seamless. I still do not know how to make a
@ViewModelScoped
, but for now I have workaround.
😍 1
a
yeah, need to solve and have direct migration of
@ViewModelScoped
@Piotr Prus do you have a snippet or sample?
o
yes @Piotr Prus I'm also interested in that
maybe manually closing the scope? will it trigger onCleared of ViewModel? In my case I have a base screen, and some other screens which can be opened as a bottomsheet (child screens). the child screens should resolve the same viewmodel instance from the base screen. The resolve part works fine but I can't dispose the viewmodel when the base screen is closed. Can anyone help with this?
Also, need to re-create the ViewModel instance when the base screen is opened again. I get close scope exception when I try to resolve it again.
a
isn't too complex here to relay on ViewModel's scope? Just wondering it's a Android hard case that could be runned with simple Activity scope
o
my app is a jetpack compose app with a single activity. don't you think it's a bad idea to relay on the activities lifecycle?
a
my app is a jetpack compose app with a single activity. don't you think it's a bad idea to relay on the activities lifecycle?
in a default way, you don't really need scope. Depends yoru usage
@Piotr Prus any update on your usage of @ViewModelScope ?
p
Sorry Arnaud for not replying. We dropped this idea and rearranged how we scope the usecases. I have this conversation saved, to get back to it, but currently I cannot promise any dates
👍 1
105 Views