-
Notifications
You must be signed in to change notification settings - Fork 50
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
How to inject VM interface rather that concrete class using koin? #346
Comments
Have you call |
Yeah, it's started correctly, in fact the error i get is org.koin.core.error.NoBeanDefFoundException: No definition found for type 'viewmodels.LoginViewModel' and qualifier 'loginVM'. Check your Modules configuration and add missing type and/or qualifier!
at org.koin.core.scope.Scope.throwDefinitionNotFound(Scope.kt:301)
at org.koin.core.scope.Scope.resolveValue(Scope.kt:271)
at org.koin.core.scope.Scope.resolveInstance(Scope.kt:233)
at org.koin.core.scope.Scope.get(Scope.kt:212)
at moe.tlaster.precompose.koin.KoinKt$resolveViewModel$1.invoke(Koin.kt:44)
at moe.tlaster.precompose.koin.KoinKt$resolveViewModel$1.invoke(Koin.kt:43)
at moe.tlaster.precompose.stateholder.StateHolder.getOrPut(StateHolder.kt:18)
.... |
You might need to try |
fun <T : ViewModel> koinViewModel(
vmClass: KClass<T>,
//... interface ILoginViewModel : IBaseViewModel {
suspend fun getAppStartupCount(): Int?
suspend fun addAppStartupCount()
suspend fun resetAppStartupCount()
//... Maybe i need some refactor on my side? |
Oops, my fault, I forgot the generic limitation of the
|
Thx for reply. @Composable
fun LoginScreen() {
// val viewModel: ILoginViewModel = getKoinInstance() -> not bound to lifecycle
// val viewModel:ILoginViewModel = viewModel(LoginViewModel::class) {
// LoginViewModel()
// } -> same as following solution
val viewModel: ILoginViewModel = koinViewModel(LoginViewModel::class, named("loginVM")) // not retrieved from Koin DI cause i'm using interface Im looking for an alternative lib for mocking, maybe with more luck :) |
Yeah this is the first idea that i had, but before start a pr i was looking for a pre baked solution 😀 |
ok @Tlaster i resolved it using this fun: @Composable
fun <T : IBaseViewModel> resolveViewModel(
vmClass: KClass<T>,
stateHolder: StateHolder = checkNotNull(LocalStateHolder.current) {
"No StateHolder was provided via LocalStateHolder"
},
key: String? = null,
scope: Scope = LocalKoinScope.current,
qualifier: Qualifier? = null,
parameters: ParametersDefinition? = null,
): T {
return stateHolder.getOrPut(qualifier?.value ?: key ?: vmClass.canonicalName ?: "") {
scope.get(vmClass, qualifier, parameters)
}
} I don't like very much the bounding to IBaseViewModel because maybe i will need to retrieve VM of other kind, but by now i can run tests and app with correctly injected/retrieved VM. In any case, thanks for the answers and for your work! |
Hi, for testing purpose i need to inject/retrieve viewmodels inside composable functions using interfaces rather that concrete classes (Koin for DI).
For mocking i use MocKMP, actually the only mocking lib in KMM env.
It works well, but can mock just interfaces (with Mockito you can mock classes too).
Now i have something like this, but when testing koin can not find vm class injected.
There isn't a way to find vm concrete class by it's interface in stateholder?
Thx
The text was updated successfully, but these errors were encountered: