commonMain.org.kodein.di.internal.DIBuilderImpl.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of kodein-di-js Show documentation
Show all versions of kodein-di-js Show documentation
KODEIN Dependency Injection Core
package org.kodein.di.internal
import org.kodein.di.*
import org.kodein.di.bindings.*
import org.kodein.type.TypeToken
import org.kodein.type.erasedComp
import org.kodein.type.generic
internal open class DIBuilderImpl internal constructor(
private val moduleName: String?,
private val prefix: String,
internal val importedModules: MutableSet,
override val containerBuilder: DIContainerBuilderImpl
) : DI.Builder {
override val contextType = TypeToken.Any
override val scope: Scope get() = NoScope() // Recreating a new NoScope every-time *on purpose*!
override val explicitContext: Boolean get() = false
inner class TypeBinder internal constructor(val type: TypeToken, val tag: Any?, val overrides: Boolean?) : DI.Builder.TypeBinder {
internal val containerBuilder get() = [email protected]
override infix fun with(binding: DIBinding) = containerBuilder.bind(DI.Key(binding.contextType, binding.argType, type, tag), binding, moduleName, overrides)
}
inner class DirectBinder internal constructor(private val _tag: Any?, private val _overrides: Boolean?) : DI.Builder.DirectBinder {
override infix fun from(binding: DIBinding) {
if (binding.createdType == TypeToken.Unit) {
throw IllegalArgumentException("Using `bind() from` with a *Unit* ${binding.factoryName()} is most likely an error. If you are sure you want to bind the Unit type, please use `bind() with ${binding.factoryName()}`.")
}
containerBuilder.bind(DI.Key(binding.contextType, binding.argType, binding.createdType, _tag), binding, moduleName, _overrides)
}
}
inner class ConstantBinder internal constructor(private val _tag: Any, private val _overrides: Boolean?) : DI.Builder.ConstantBinder {
@Suppress("FunctionName")
override fun With(valueType: TypeToken, value: T) = Bind(tag = _tag, overrides = _overrides, binding = InstanceBinding(valueType, value))
}
@Suppress("FunctionName")
override fun Bind(type: TypeToken, tag: Any?, overrides: Boolean?) = TypeBinder(type, tag, overrides)
@Suppress("FunctionName")
override fun Bind(tag: Any?, overrides: Boolean?, binding: DIBinding<*, *, T>) {
containerBuilder.bind(
key = DI.Key(binding.contextType, binding.argType, binding.createdType, tag = tag),
binding = binding,
fromModule = moduleName,
overrides = overrides,
)
}
@Suppress("UNCHECKED_CAST")
override fun BindSet(tag: Any?, overrides: Boolean?, binding: DIBinding<*, *, T>) {
val setType = erasedComp(Set::class, binding.createdType) as TypeToken>
val setKey = DI.Key(binding.contextType, binding.argType, setType, tag)
val setBinding = containerBuilder.bindingsMap[setKey]?.first() ?: throw IllegalStateException("No set binding to $setKey")
setBinding.binding as? BaseMultiBinding<*, *, T> ?: throw IllegalStateException("$setKey is associated to a ${setBinding.binding.factoryName()} while it should be associated with bindingSet")
(setBinding.binding.set as MutableSet>).add(binding)
}
@Suppress("FunctionName")
override fun Bind(tag: Any?, overrides: Boolean?): DirectBinder = DirectBinder(tag, overrides)
override fun constant(tag: Any, overrides: Boolean?) = ConstantBinder(tag, overrides)
override fun import(module: DI.Module, allowOverride: Boolean) {
val moduleName = prefix + module.name
if (moduleName.isNotEmpty() && moduleName in importedModules) {
throw IllegalStateException("Module \"$moduleName\" has already been imported!")
}
importedModules += moduleName
DIBuilderImpl(moduleName, prefix + module.prefix, importedModules, containerBuilder.subBuilder(allowOverride, module.allowSilentOverride)).apply(module.init)
}
override fun importAll(modules: Iterable, allowOverride: Boolean) =
modules.forEach { import(it, allowOverride) }
override fun importAll(vararg modules: DI.Module, allowOverride: Boolean) =
modules.forEach { import(it, allowOverride) }
override fun importOnce(module: DI.Module, allowOverride: Boolean) {
if (module.name.isEmpty())
throw IllegalStateException("importOnce must be given a named module.")
if (module.name !in importedModules)
import(module, allowOverride)
}
override fun onReady(cb: DirectDI.() -> Unit) = containerBuilder.onReady(cb)
override fun RegisterContextTranslator(translator: ContextTranslator<*, *>) = containerBuilder.registerContextTranslator(translator)
}
internal open class DIMainBuilderImpl(allowSilentOverride: Boolean) : DIBuilderImpl(null, "", HashSet(), DIContainerBuilderImpl(true, allowSilentOverride, HashMap(), ArrayList(), ArrayList())), DI.MainBuilder {
override val externalSources: MutableList = ArrayList()
override var fullDescriptionOnError: Boolean = DI.defaultFullDescriptionOnError
override var fullContainerTreeOnError: Boolean = DI.defaultFullContainerTreeOnError
override fun extend(di: DI, allowOverride: Boolean, copy: Copy) {
val keys = copy.keySet(di.container.tree)
containerBuilder.extend(di.container, allowOverride, keys)
externalSources += di.container.tree.externalSources
importedModules.addAll(
containerBuilder.bindingsMap
.flatMap { it.value.map { it.fromModule } }
.filterNotNull()
)
}
override fun extend(directDI: DirectDI, allowOverride: Boolean, copy: Copy) {
val keys = copy.keySet(directDI.container.tree)
containerBuilder.extend(directDI.container, allowOverride, keys)
externalSources += directDI.container.tree.externalSources
importedModules.addAll(
containerBuilder.bindingsMap
.flatMap { it.value.map { it.fromModule } }
.filterNotNull()
)
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy