
com.github.salomonbrys.kodein.references.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of kodein-core Show documentation
Show all versions of kodein-core Show documentation
Kotlin Dependency Injection Core
The newest version!
package com.github.salomonbrys.kodein
import com.github.salomonbrys.kodein.bindings.Binding
import com.github.salomonbrys.kodein.bindings.BindingKodein
import com.github.salomonbrys.kodein.bindings.NoArgBinding
import com.github.salomonbrys.kodein.bindings.NoArgBindingKodein
import com.github.salomonbrys.kodein.internal.synchronizedIfNull
/**
* A Function that creates a reference.
*/
interface RefMaker {
/**
* A Function that creates a reference.
*
* @param T The type of the referenced object.
* @param creator A function that can create a new T.
* @return The referenced object and a function that returns the same object if the reference is still valid.
*/
fun make(creator: () -> T): Pair T?>
}
/**
* Concrete referenced singleton provider: will always return the instance managed by the given reference.
*
* @param T The type of the instance.
* @property refMaker Reference Maker that defines the kind of reference being used.
* @property creator A function that should always create a new object.
*/
class RefSingletonBinding(override val createdType: TypeToken, val refMaker: RefMaker, val creator: NoArgBindingKodein.() -> T) : NoArgBinding {
// Should always return the same object or null.
private var _ref: (() -> T?) = { null }
private val _lock = Any()
override fun factoryName() = "refSingleton(${TTOf(refMaker).simpleDispString ()})"
override fun factoryFullName() = "refSingleton(${TTOf(refMaker).fullDispString()})"
override fun getInstance(kodein: NoArgBindingKodein, key: Kodein.Key): T {
var ret: T? = null
synchronizedIfNull(_lock, { _ref() }, { return it }) {
val pair = refMaker.make {
kodein.creator()
}
_ref = pair.second
ret = pair.first
}
return ret!!
}
}
/**
* Concrete referenced multiton factory: for the same argument, will always return the instance managed by the given reference.
*
* @param T The type of the instance.
* @property argType The type of the argument, *used for debug print only*.
* @property createdType The type of the created object, *used for debug print only*.
* @property refMaker Reference Maker that defines the kind of reference being used.
* @property creator A function that should always create a new object.
*/
class RefMultitonBinding(override val argType: TypeToken, override val createdType: TypeToken, val refMaker: RefMaker, val creator: BindingKodein.(A) -> T): Binding {
private val _refs = newConcurrentMap T?>()
override fun factoryName() = "refMultiton(${TTOf(refMaker).simpleDispString()})"
override fun factoryFullName() = "refMultiton(${TTOf(refMaker).fullDispString()})"
override fun getInstance(kodein: BindingKodein, key: Kodein.Key, arg: A): T {
var ret: T? = null
synchronizedIfNull(_refs, { _refs[arg]?.invoke() }, { return it }) {
val pair = refMaker.make { kodein.creator(arg) }
_refs[arg] = pair.second
ret = pair.first
}
return ret!!
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy