Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
Romain Boisselle committed Dec 24, 2020
2 parents c830267 + 0838a9c commit 998c66d
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 14 deletions.
8 changes: 4 additions & 4 deletions kodein-di/src/commonMain/kotlin/org/kodein/di/DIBuilder.kt
Original file line number Diff line number Diff line change
Expand Up @@ -146,12 +146,12 @@ public inline fun <reified T: Any> DI.Builder.instance(instance: T): InstanceBin
//endregion

//region ContextTranslator
public inline fun <reified C : Any, reified S : Any> contextTranslator(noinline t: (C) -> S?): ContextTranslator<C, S> = SimpleContextTranslator(generic(), generic(), t)
public inline fun <reified C : Any, reified S : Any> contextTranslator(noinline t: DirectDI.(C) -> S?): ContextTranslator<C, S> = SimpleContextTranslator(generic(), generic(), t)

public inline fun <reified C : Any, reified S : Any> DI.Builder.registerContextTranslator(noinline t: (C) -> S?): Unit = RegisterContextTranslator(contextTranslator(t))
public inline fun <reified C : Any, reified S : Any> DI.Builder.registerContextTranslator(noinline t: DirectDI.(C) -> S?): Unit = RegisterContextTranslator(contextTranslator(t))

public inline fun <reified S : Any> contextFinder(noinline t: () -> S) : ContextTranslator<Any, S> = SimpleAutoContextTranslator(generic(), t)
public inline fun <reified S : Any> contextFinder(noinline t: DirectDI.() -> S) : ContextTranslator<Any, S> = SimpleAutoContextTranslator(generic(), t)

public inline fun <reified S : Any> DI.Builder.registerContextFinder(noinline t: () -> S): Unit = RegisterContextTranslator(contextFinder(t))
public inline fun <reified S : Any> DI.Builder.registerContextFinder(noinline t: DirectDI.() -> S): Unit = RegisterContextTranslator(contextFinder(t))
//endregion

16 changes: 9 additions & 7 deletions kodein-di/src/commonMain/kotlin/org/kodein/di/bindings/scopes.kt
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -172,26 +174,26 @@ public class SingleItemScopeRegistry : ScopeRegistry() {
public interface ContextTranslator<in C : Any, S : Any> {
public val contextType: TypeToken<in C>
public val scopeType: TypeToken<in S>
public fun translate(ctx: C): S?
public fun translate(di: DirectDI, ctx: C): S?
}

public class SimpleContextTranslator<in C : Any, S: Any>(override val contextType: TypeToken<in C>, override val scopeType: TypeToken<in S>, private val t: (ctx: C) -> S?) : ContextTranslator<C, S> {
override fun translate(ctx: C): S? = t(ctx)
public class SimpleContextTranslator<in C : Any, S: Any>(override val contextType: TypeToken<in C>, override val scopeType: TypeToken<in S>, private val t: DirectDI.(ctx: C) -> S?) : ContextTranslator<C, S> {
override fun translate(di: DirectDI, ctx: C): S? = di.t(ctx)
override fun toString(): String = "()"
}

public class SimpleAutoContextTranslator<S: Any>(override val scopeType: TypeToken<in S>, private val t: () -> S) : ContextTranslator<Any, S> {
public class SimpleAutoContextTranslator<S: Any>(override val scopeType: TypeToken<in S>, private val t: DirectDI.() -> S) : ContextTranslator<Any, S> {
override val contextType: TypeToken<Any> 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 <C : Any, S: Any> ContextTranslator<C, S>.toKContext(ctx: C): DIContext<S>? = translate(ctx)?.let { DIContext(scopeType, it) }
public fun <C : Any, S: Any> ContextTranslator<C, S>.toKContext(di: DirectDI, ctx: C): DIContext<S>? = translate(di, ctx)?.let { DIContext(scopeType, it) }

internal class CompositeContextTranslator<in C : Any, I : Any, S: Any>(val src: ContextTranslator<C, I>, val dst: ContextTranslator<I, S>) : ContextTranslator<C, S> {
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)"
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<Any>
val originalContext = DIContext(key.contextType, context) as DIContext<Any>
val kContext = translator?.toKContext(DirectDIImpl(this, originalContext), context) ?: originalContext
key as DI.Key<Any, A, T>
val bindingDI = bindingDI(key, kContext, definition.tree, overrideLevel)
return definition.binding.getFactory(key, bindingDI)
Expand All @@ -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<Any>
val originalContext = DIContext(key.contextType, context) as DIContext<Any>
val kContext = translator?.toKContext(DirectDIImpl(this, originalContext), context) ?: originalContext
key as DI.Key<Any, A, T>
val bindingDI = bindingDI(key, kContext, definition.tree, overrideLevel)
return definition.binding.getFactory(key, bindingDI)
Expand Down Expand Up @@ -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<Any>
val originalContext = DIContext(key.contextType, context) as DIContext<Any>
val kContext = translator?.toKContext(DirectDIImpl(this, originalContext), context) ?: originalContext
key as DI.Key<Any, A, T>
val bindingDI = bindingDI(key, kContext, definition.tree, overrideLevel)
definition.binding.getFactory(key, bindingDI)
Expand Down
18 changes: 18 additions & 0 deletions kodein-di/src/commonTest/kotlin/org/kodein/di/Tests_13_Scope.kt
Original file line number Diff line number Diff line change
Expand Up @@ -249,5 +249,23 @@ class Tests_13_Scope {
assertEquals(FullName("Laila", "BRYS"), fn2)
}

@Test
fun test_10_ContextFinderInDI() {
val registries = HashMap<Name, ScopeRegistry>()
val nameScope = object : Scope<Name> {
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<Name> { instance<CurrentName>().current }
}

assertEquals(FullName("Salomon", "BRYS"), di.instance<FullName>())
di.instance<CurrentName>().current = Name("Laila")
assertEquals(FullName("Laila", "BRYS"), di.instance<FullName>())
}


}

0 comments on commit 998c66d

Please sign in to comment.