From 0838a9cf01612a8550ed1f21b601beca0cab9271 Mon Sep 17 00:00:00 2001 From: Salomon BRYS Date: Tue, 22 Dec 2020 17:57:25 +0100 Subject: [PATCH] ContextTranslator now works in a DI receiver. --- .../org/kodein/di/tornadofx/extension.kt | 2 +- kodein-di/build.gradle.kts | 2 +- .../kotlin/org/kodein/di/DIBuilder.kt | 8 ++++---- .../kotlin/org/kodein/di/bindings/scopes.kt | 16 +++++++++------- .../org/kodein/di/internal/DIContainerImpl.kt | 9 ++++++--- .../kotlin/org/kodein/di/Tests_13_Scope.kt | 18 ++++++++++++++++++ 6 files changed, 39 insertions(+), 16 deletions(-) diff --git a/framework/tornadofx/kodein-di-framework-tornadofx-jvm/src/main/kotlin/org/kodein/di/tornadofx/extension.kt b/framework/tornadofx/kodein-di-framework-tornadofx-jvm/src/main/kotlin/org/kodein/di/tornadofx/extension.kt index 491dc8d2..05cbb1e2 100644 --- a/framework/tornadofx/kodein-di-framework-tornadofx-jvm/src/main/kotlin/org/kodein/di/tornadofx/extension.kt +++ b/framework/tornadofx/kodein-di-framework-tornadofx-jvm/src/main/kotlin/org/kodein/di/tornadofx/extension.kt @@ -10,7 +10,7 @@ import kotlin.reflect.* @Suppress("UNCHECKED_CAST") public fun DI.MainBuilder.installTornadoSource() { externalSources += ExternalSource { key -> - val elementType = key.type.getRaw()?.jvmType as Class<*>? + val elementType = key.type.getRaw().jvmType as Class<*>? // Check if the elementType is injectable by TornadoFX di container (infine if its a Component) if (elementType != null && diff --git a/kodein-di/build.gradle.kts b/kodein-di/build.gradle.kts index fa2d7270..9a37e34c 100644 --- a/kodein-di/build.gradle.kts +++ b/kodein-di/build.gradle.kts @@ -7,7 +7,7 @@ kodein { common { main.dependencies { - api("org.kodein.type:kodein-type:1.3.0") + api("org.kodein.type:kodein-type:1.4.0") } test.dependencies { implementation(project(":test-utils")) 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()) + } + }