diff --git a/kodein-di/src/commonMain/kotlin/org/kodein/di/DIBuilder.kt b/kodein-di/src/commonMain/kotlin/org/kodein/di/DIBuilder.kt index f62d6c9b..6cf19e59 100644 --- a/kodein-di/src/commonMain/kotlin/org/kodein/di/DIBuilder.kt +++ b/kodein-di/src/commonMain/kotlin/org/kodein/di/DIBuilder.kt @@ -146,12 +146,12 @@ public inline fun DI.Builder.instance(instance: T): InstanceBin //endregion //region ContextTranslator -public inline fun contextTranslator(noinline t: (C) -> S?): ContextTranslator = SimpleContextTranslator(generic(), generic(), t) +public inline fun contextTranslator(noinline t: DirectDI.(C) -> S?): ContextTranslator = SimpleContextTranslator(generic(), generic(), t) -public inline fun DI.Builder.registerContextTranslator(noinline t: (C) -> S?): Unit = RegisterContextTranslator(contextTranslator(t)) +public inline fun DI.Builder.registerContextTranslator(noinline t: DirectDI.(C) -> S?): Unit = RegisterContextTranslator(contextTranslator(t)) -public inline fun contextFinder(noinline t: () -> S) : ContextTranslator = SimpleAutoContextTranslator(generic(), t) +public inline fun contextFinder(noinline t: DirectDI.() -> S) : ContextTranslator = SimpleAutoContextTranslator(generic(), t) -public inline fun DI.Builder.registerContextFinder(noinline t: () -> S): Unit = RegisterContextTranslator(contextFinder(t)) +public inline fun DI.Builder.registerContextFinder(noinline t: DirectDI.() -> S): Unit = RegisterContextTranslator(contextFinder(t)) //endregion diff --git a/kodein-di/src/commonMain/kotlin/org/kodein/di/bindings/scopes.kt b/kodein-di/src/commonMain/kotlin/org/kodein/di/bindings/scopes.kt index 01a96773..f7256df4 100644 --- a/kodein-di/src/commonMain/kotlin/org/kodein/di/bindings/scopes.kt +++ b/kodein-di/src/commonMain/kotlin/org/kodein/di/bindings/scopes.kt @@ -1,6 +1,8 @@ package org.kodein.di.bindings +import org.kodein.di.DI import org.kodein.di.DIContext +import org.kodein.di.DirectDI import org.kodein.di.Volatile import org.kodein.di.internal.maySynchronized import org.kodein.di.internal.newConcurrentMap @@ -172,26 +174,26 @@ public class SingleItemScopeRegistry : ScopeRegistry() { public interface ContextTranslator { public val contextType: TypeToken public val scopeType: TypeToken - public fun translate(ctx: C): S? + public fun translate(di: DirectDI, ctx: C): S? } -public class SimpleContextTranslator(override val contextType: TypeToken, override val scopeType: TypeToken, private val t: (ctx: C) -> S?) : ContextTranslator { - override fun translate(ctx: C): S? = t(ctx) +public class SimpleContextTranslator(override val contextType: TypeToken, override val scopeType: TypeToken, private val t: DirectDI.(ctx: C) -> S?) : ContextTranslator { + override fun translate(di: DirectDI, ctx: C): S? = di.t(ctx) override fun toString(): String = "()" } -public class SimpleAutoContextTranslator(override val scopeType: TypeToken, private val t: () -> S) : ContextTranslator { +public class SimpleAutoContextTranslator(override val scopeType: TypeToken, private val t: DirectDI.() -> S) : ContextTranslator { override val contextType: TypeToken get() = TypeToken.Any - override fun translate(ctx: Any): S = t() + override fun translate(di: DirectDI, ctx: Any): S = di.t() override fun toString(): String = "(${scopeType.simpleDispString()} -> ${contextType.simpleDispString()})" } -public fun ContextTranslator.toKContext(ctx: C): DIContext? = translate(ctx)?.let { DIContext(scopeType, it) } +public fun ContextTranslator.toKContext(di: DirectDI, ctx: C): DIContext? = translate(di, ctx)?.let { DIContext(scopeType, it) } internal class CompositeContextTranslator(val src: ContextTranslator, val dst: ContextTranslator) : ContextTranslator { override val contextType get() = src.contextType override val scopeType get() = dst.scopeType - override fun translate(ctx: C): S? = src.translate(ctx)?.let { dst.translate(it) } + override fun translate(di: DirectDI, ctx: C): S? = src.translate(di, ctx)?.let { dst.translate(di, it) } override fun toString() = "($src -> $dst)" } diff --git a/kodein-di/src/commonMain/kotlin/org/kodein/di/internal/DIContainerImpl.kt b/kodein-di/src/commonMain/kotlin/org/kodein/di/internal/DIContainerImpl.kt index 0c398acb..29cd6b5c 100644 --- a/kodein-di/src/commonMain/kotlin/org/kodein/di/internal/DIContainerImpl.kt +++ b/kodein-di/src/commonMain/kotlin/org/kodein/di/internal/DIContainerImpl.kt @@ -126,7 +126,8 @@ internal class DIContainerImpl private constructor( if (it.size == 1) { val (_, definition, translator) = it[0] node?.check(key, 0) - val kContext = translator?.toKContext(context) ?: DIContext(key.contextType, context) as DIContext + val originalContext = DIContext(key.contextType, context) as DIContext + val kContext = translator?.toKContext(DirectDIImpl(this, originalContext), context) ?: originalContext key as DI.Key val bindingDI = bindingDI(key, kContext, definition.tree, overrideLevel) return definition.binding.getFactory(key, bindingDI) @@ -152,7 +153,8 @@ internal class DIContainerImpl private constructor( if (result.size == 1) { val (_, definition, translator) = result[0] node?.check(key, overrideLevel) - val kContext = translator?.toKContext(context) ?: DIContext(key.contextType, context) as DIContext + val originalContext = DIContext(key.contextType, context) as DIContext + val kContext = translator?.toKContext(DirectDIImpl(this, originalContext), context) ?: originalContext key as DI.Key val bindingDI = bindingDI(key, kContext, definition.tree, overrideLevel) return definition.binding.getFactory(key, bindingDI) @@ -198,7 +200,8 @@ internal class DIContainerImpl private constructor( return result.map { (_, definition, translator) -> node?.check(key, overrideLevel) - val kContext = translator?.toKContext(context) ?: DIContext(key.contextType, context) as DIContext + val originalContext = DIContext(key.contextType, context) as DIContext + val kContext = translator?.toKContext(DirectDIImpl(this, originalContext), context) ?: originalContext key as DI.Key val bindingDI = bindingDI(key, kContext, definition.tree, overrideLevel) definition.binding.getFactory(key, bindingDI) diff --git a/kodein-di/src/commonTest/kotlin/org/kodein/di/Tests_13_Scope.kt b/kodein-di/src/commonTest/kotlin/org/kodein/di/Tests_13_Scope.kt index 9151929a..fe259bb8 100644 --- a/kodein-di/src/commonTest/kotlin/org/kodein/di/Tests_13_Scope.kt +++ b/kodein-di/src/commonTest/kotlin/org/kodein/di/Tests_13_Scope.kt @@ -249,5 +249,23 @@ class Tests_13_Scope { assertEquals(FullName("Laila", "BRYS"), fn2) } + @Test + fun test_10_ContextFinderInDI() { + val registries = HashMap() + val nameScope = object : Scope { + override fun getRegistry(context: Name) = registries.getOrPut(context) { StandardScopeRegistry() } + } + class CurrentName(var current: Name) + val di = DI.direct { + bind() from scoped(nameScope).singleton { FullName(context.firstName, "BRYS") } + bind() from singleton { CurrentName(Name("Salomon")) } + registerContextFinder { instance().current } + } + + assertEquals(FullName("Salomon", "BRYS"), di.instance()) + di.instance().current = Name("Laila") + assertEquals(FullName("Laila", "BRYS"), di.instance()) + } + }