Alexandru Caraus
08/08/2024, 9:46 AMAlexandru Caraus
08/08/2024, 9:47 AMAlexandru Caraus
08/08/2024, 9:47 AM@KoinViewModel
class AViewModel(
@InjectedParam holderA: HolderA,
@InjectedParam holderB: HolderB,
@InjectedParam scope: CoroutineScope
): ViewModel(scope) {}
@Factory
class HolderA(
@InjectedParam scope: CoroutineScope
): CoroutineScope by scope {}
@Factory
class HolderB(
@InjectedParam scope: CoroutineScope
): CoroutineScope by scope {}
Alexandru Caraus
08/08/2024, 9:48 AMAlexandru Caraus
08/08/2024, 9:48 AMfun createAViewModel(): AViewModel {
val scope = CoroutineScope(SupervisorJob() + Dispatchers.Main)
val holderA = koinInject<HolderA> { parametersOf(scope) }
val holderB = koinInject<HolderB> { parametersOf(scope) }
val vm = koinViewModel<AViewModel> { parametersOf(holderA, holderB, scope) }
return vm
}
Alexandru Caraus
08/08/2024, 9:49 AMAlexandru Caraus
08/08/2024, 12:24 PMAlexandru Caraus
08/08/2024, 12:24 PMAlexandru Caraus
08/08/2024, 12:24 PMAlexandru Caraus
08/08/2024, 12:24 PMval vm = scopedKoinViewModel<AViewModel>()
@Factory
fun uiScope(dispatchers: Dispatchers) = CoroutineScope(SupervisorJob() + dispatchers.ui)
@Composable
inline fun <reified T : ViewModel> scopedKoinViewModel(): T {
val koinScope = currentKoinScope()
val coroutineScope = koinInject<CoroutineScope>()
val dependencies = getDependencies<T>(InjectedParam::class)
.map { clazz -> koinScope.get<Any>(clazz.java) { parametersOf(coroutineScope) } }
.plus(coroutineScope)
return koinViewModel<T> { parametersOf(*dependencies.toTypedArray()) }
}
inline fun <reified T : ViewModel> getDependencies(
annotationClass: KClass<out Annotation>
): List<KClass<*>> =
T::class.primaryConstructor?.parameters
?.filter { it.findAnnotation<Annotation>()?.annotationClass == annotationClass }
?.map { parameters -> parameters.type.classifier as? KClass<*> ?: Any::class }
?: emptyList()
Alexandru Caraus
08/08/2024, 1:13 PMAlexandru Caraus
08/08/2024, 1:13 PM@Composable
inline fun <reified T : ViewModel> scopedKoinViewModel(
providedParams: List<Any> = emptyList(),
): T {
val koinScope = currentKoinScope()
val coroutineScope = koinInject<CoroutineScope>(qualifier = named("main"))
val dependencies = getInjectedParamDependencies<T>()
.filterNot { clazz -> providedParams.any { provided -> provided::class == clazz } }
.map { clazz -> koinScope.get<Any>(clazz) { parametersOf(coroutineScope) } }
.plus(providedParams)
return koinViewModel<T> { parametersOf(*dependencies.toTypedArray(), coroutineScope) }
}
inline fun <reified T : ViewModel> getInjectedParamDependencies(
annotationClass: KClass<out Annotation> = InjectedParam::class,
): List<KClass<*>> =
T::class.primaryConstructor?.parameters
?.filter { it.findAnnotation<Annotation>()?.annotationClass == annotationClass }
?.map { parameters -> parameters.type.classifier as? KClass<*> ?: Any::class }
?: emptyList()