K2: Add ability identify DI components by string key instead of KClass
It allows having several the same typed-component in the container
This commit is contained in:
committed by
Space Team
parent
58c1b5dd1f
commit
dab50daf56
@@ -24,6 +24,10 @@ abstract class FirSession @PrivateSessionConstructor constructor(
|
||||
return generateAccessor(T::class)
|
||||
}
|
||||
|
||||
inline fun <reified T : FirSessionComponent> sessionComponentAccessor(id: String): ArrayMapAccessor<FirSessionComponent, FirSessionComponent, T> {
|
||||
return generateAccessor(id)
|
||||
}
|
||||
|
||||
inline fun <reified T : FirSessionComponent> nullableSessionComponentAccessor(): NullableArrayMapAccessor<FirSessionComponent, FirSessionComponent, T> {
|
||||
return generateNullableAccessor(T::class)
|
||||
}
|
||||
@@ -38,6 +42,11 @@ abstract class FirSession @PrivateSessionConstructor constructor(
|
||||
registerComponent(tClass, value)
|
||||
}
|
||||
|
||||
@SessionConfiguration
|
||||
fun register(keyQualifiedName: String, value: FirSessionComponent) {
|
||||
registerComponent(keyQualifiedName, value)
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
val moduleData = nullableModuleData ?: return "Libraries session"
|
||||
return "Source session for module ${moduleData.name}"
|
||||
|
||||
@@ -19,7 +19,6 @@ abstract class AbstractArrayMapOwner<K : Any, V : Any> : Iterable<V> {
|
||||
protected abstract val typeRegistry: TypeRegistry<K, V>
|
||||
|
||||
abstract class AbstractArrayMapAccessor<K : Any, V : Any, T : V>(
|
||||
protected val key: KClass<out K>,
|
||||
protected val id: Int
|
||||
) {
|
||||
protected fun extractValue(thisRef: AbstractArrayMapOwner<K, V>): T? {
|
||||
@@ -28,7 +27,11 @@ abstract class AbstractArrayMapOwner<K : Any, V : Any> : Iterable<V> {
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract fun registerComponent(tClass: KClass<out K>, value: V)
|
||||
protected abstract fun registerComponent(keyQualifiedName: String, value: V)
|
||||
|
||||
protected fun registerComponent(tClass: KClass<out K>, value: V) {
|
||||
registerComponent(tClass.qualifiedName!!, value)
|
||||
}
|
||||
|
||||
final override fun iterator(): Iterator<V> = arrayMap.iterator()
|
||||
|
||||
@@ -40,21 +43,20 @@ abstract class AbstractArrayMapOwner<K : Any, V : Any> : Iterable<V> {
|
||||
}
|
||||
|
||||
class ArrayMapAccessor<K : Any, V : Any, T : V>(
|
||||
key: KClass<out K>,
|
||||
private val keyQualifiedName: String,
|
||||
id: Int,
|
||||
val default: T? = null
|
||||
) : AbstractArrayMapOwner.AbstractArrayMapAccessor<K, V, T>(key, id), ReadOnlyProperty<AbstractArrayMapOwner<K, V>, V> {
|
||||
) : AbstractArrayMapOwner.AbstractArrayMapAccessor<K, V, T>(id), ReadOnlyProperty<AbstractArrayMapOwner<K, V>, V> {
|
||||
override fun getValue(thisRef: AbstractArrayMapOwner<K, V>, property: KProperty<*>): T {
|
||||
return extractValue(thisRef)
|
||||
?: default
|
||||
?: error("No '$key'($id) in array owner: $thisRef")
|
||||
?: error("No '$keyQualifiedName'($id) in array owner: $thisRef")
|
||||
}
|
||||
}
|
||||
|
||||
class NullableArrayMapAccessor<K : Any, V : Any, T : V>(
|
||||
key: KClass<out K>,
|
||||
id: Int
|
||||
) : AbstractArrayMapOwner.AbstractArrayMapAccessor<K, V, T>(key, id), ReadOnlyProperty<AbstractArrayMapOwner<K, V>, V?> {
|
||||
) : AbstractArrayMapOwner.AbstractArrayMapAccessor<K, V, T>(id), ReadOnlyProperty<AbstractArrayMapOwner<K, V>, V?> {
|
||||
override fun getValue(thisRef: AbstractArrayMapOwner<K, V>, property: KProperty<*>): T? {
|
||||
return extractValue(thisRef)
|
||||
}
|
||||
@@ -65,19 +67,27 @@ abstract class TypeRegistry<K : Any, V : Any> {
|
||||
private val idCounter = AtomicInteger(0)
|
||||
|
||||
fun <T : V, KK : K> generateAccessor(kClass: KClass<KK>, default: T? = null): ArrayMapAccessor<K, V, T> {
|
||||
return ArrayMapAccessor(kClass, getId(kClass), default)
|
||||
return ArrayMapAccessor(kClass.qualifiedName!!, getId(kClass), default)
|
||||
}
|
||||
|
||||
fun <T : V> generateAccessor(keyQualifiedName: String, default: T? = null): ArrayMapAccessor<K, V, T> {
|
||||
return ArrayMapAccessor(keyQualifiedName, getId(keyQualifiedName), default)
|
||||
}
|
||||
|
||||
fun <T : V, KK : K> generateNullableAccessor(kClass: KClass<KK>): NullableArrayMapAccessor<K, V, T> {
|
||||
return NullableArrayMapAccessor(kClass, getId(kClass))
|
||||
return NullableArrayMapAccessor(getId(kClass))
|
||||
}
|
||||
|
||||
fun <KK : K> generateAnyNullableAccessor(kClass: KClass<KK>): NullableArrayMapAccessor<K, V, *> {
|
||||
return NullableArrayMapAccessor(kClass, getId(kClass))
|
||||
return NullableArrayMapAccessor(getId(kClass))
|
||||
}
|
||||
|
||||
fun <T : K> getId(kClass: KClass<T>): Int {
|
||||
return idPerType.customComputeIfAbsent(kClass.qualifiedName!!) { idCounter.getAndIncrement() }
|
||||
return getId(kClass.qualifiedName!!)
|
||||
}
|
||||
|
||||
fun getId(keyQualifiedName: String): Int {
|
||||
return idPerType.customComputeIfAbsent(keyQualifiedName) { idCounter.getAndIncrement() }
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -25,8 +25,8 @@ abstract class AttributeArrayOwner<K : Any, T : Any> protected constructor(
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
constructor() : this(EmptyArrayMap as ArrayMap<T>)
|
||||
|
||||
final override fun registerComponent(tClass: KClass<out K>, value: T) {
|
||||
val id = typeRegistry.getId(tClass)
|
||||
final override fun registerComponent(keyQualifiedName: String, value: T) {
|
||||
val id = typeRegistry.getId(keyQualifiedName)
|
||||
when (arrayMap.size) {
|
||||
0 -> {
|
||||
arrayMap = OneElementArrayMap(value, id)
|
||||
|
||||
@@ -15,12 +15,12 @@ abstract class ComponentArrayOwner<K : Any, V : Any> : AbstractArrayMapOwner<K,
|
||||
final override val arrayMap: ArrayMap<V> =
|
||||
ArrayMapImpl()
|
||||
|
||||
final override fun registerComponent(tClass: KClass<out K>, value: V) {
|
||||
val id = typeRegistry.getId(tClass)
|
||||
final override fun registerComponent(keyQualifiedName: String, value: V) {
|
||||
val id = typeRegistry.getId(keyQualifiedName)
|
||||
try {
|
||||
arrayMap[id] = value
|
||||
} catch (e: Exception) {
|
||||
throw RuntimeException(createDiagnosticMessage(id, tClass), e)
|
||||
throw RuntimeException(createDiagnosticMessage(id, keyQualifiedName), e)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,10 +29,10 @@ abstract class ComponentArrayOwner<K : Any, V : Any> : AbstractArrayMapOwner<K,
|
||||
return arrayMap[id] ?: error("No '$key'($id) component in array: $this")
|
||||
}
|
||||
|
||||
private fun createDiagnosticMessage(id: Int, tClass: KClass<*>): String = buildString {
|
||||
private fun createDiagnosticMessage(id: Int, keyQualifiedName: String): String = buildString {
|
||||
appendLine("Error occurred during registration of component in array")
|
||||
appendLine("Currently registered")
|
||||
appendLine(" $id: $tClass")
|
||||
appendLine(" $id: $keyQualifiedName")
|
||||
appendLine("Registrar:")
|
||||
for ((kClass, x) in typeRegistry.allValuesThreadUnsafeForRendering()) {
|
||||
appendLine(" $x: $kClass")
|
||||
|
||||
Reference in New Issue
Block a user