koin icon indicating copy to clipboard operation
koin copied to clipboard

LocalKoinScope stuck with a closed scope

Open tlevavasseur-decathlon opened this issue 1 year ago • 1 comments

Describe the bug The issue was present in 3.4.X :

@Composable
inline fun <reified T> koinInject(
    qualifier: Qualifier? = null,
    scope: Scope = LocalKoinScope.current,
    noinline parameters: ParametersDefinition? = null,
): T = rememberKoinInject(qualifier, scope, parameters)

@OptIn(KoinInternalApi::class)
val LocalKoinScope = compositionLocalOf { getKoinContext().scopeRegistry.rootScope }

fixed in 3.5.0 :

@Composable
inline fun <reified T> koinInject(
    qualifier: Qualifier? = null,
    scope: Scope = getKoinScope(),
    noinline parameters: ParametersDefinition? = null,
): T = rememberKoinInject(qualifier, scope, parameters)

@OptIn(InternalComposeApi::class)
@Composable
fun getKoinScope(): Scope = currentComposer.run {
    remember {
        try {
            consume(LocalKoinScope)
        } catch (_: UnknownKoinContext) {
            val ctx = getKoinContext()
            warningNoContext(ctx)
            getKoinContext().scopeRegistry.rootScope
        }
    }
}

val LocalKoinScope: ProvidableCompositionLocal<Scope> = 
    compositionLocalOf { throw UnknownKoinContext() }

but reintroduced in 3.5.3 :

val LocalKoinScope: ProvidableCompositionLocal<Scope> = compositionLocalOf {
    getDefaultKoinContext().apply {
        warnNoContext()
    }.scopeRegistry.rootScope
}

private fun getDefaultKoinContext() = KoinPlatformTools.defaultContext().get()

We get stuck with a closed scope, the one active on initialization of LocalKoinScope.

To Reproduce a simple way to test it is to restart koin and the activity :

MainActivity : 

        Button(onClick = {
            restartKoin()
            context.startActivity(Intent(context, MainActivity::class.java))
        })

fun restartKoin() {
    stopKoin()
    koin = startKoin {  ... }
}

Expected behavior Like with 3.5.0 : when a new activity wants the LocalKoinScope (with koinInject()) get the currently available Koin instance.

tlevavasseur-decathlon avatar Jun 28 '24 09:06 tlevavasseur-decathlon

did you check in 4.0?

arnaudgiuliani avatar Aug 27 '24 16:08 arnaudgiuliani

still present in 4.0.0-RC2

indeed the code remains the same since 3.5.3 :

/**
 * Current Koin Scope
 */
@OptIn(KoinInternalApi::class)
val LocalKoinScope: ProvidableCompositionLocal<Scope> = compositionLocalOf {
    getDefaultKoinContext().apply {
        warnNoContext()
    }.scopeRegistry.rootScope
}

private fun getDefaultKoinContext() = KoinPlatformTools.defaultContext().get()

tlevavasseur-decathlon avatar Sep 05 '24 09:09 tlevavasseur-decathlon

ok, got it 👌

arnaudgiuliani avatar Sep 09 '24 16:09 arnaudgiuliani

Fixed in #1975

arnaudgiuliani avatar Sep 13 '24 07:09 arnaudgiuliani