diff options
Diffstat (limited to 'src/main/kotlin/moe/nea/ledger/utils/di')
-rw-r--r-- | src/main/kotlin/moe/nea/ledger/utils/di/DI.kt | 7 | ||||
-rw-r--r-- | src/main/kotlin/moe/nea/ledger/utils/di/DIProvider.kt | 1 |
2 files changed, 6 insertions, 2 deletions
diff --git a/src/main/kotlin/moe/nea/ledger/utils/di/DI.kt b/src/main/kotlin/moe/nea/ledger/utils/di/DI.kt index 6940f72..133637a 100644 --- a/src/main/kotlin/moe/nea/ledger/utils/di/DI.kt +++ b/src/main/kotlin/moe/nea/ledger/utils/di/DI.kt @@ -6,6 +6,9 @@ import java.util.Stack @Suppress("UNCHECKED_CAST") class DI { + private fun formatInjectionStack() = + injectionStack.joinToString(" -> ") + private fun <T : Any, C> internalProvide(type: Class<T>, element: AnnotatedElement? = null): T { val provider = providers[type] as BaseDIProvider<T, C> val context = if (element == null) provider.createEmptyContext() else provider.createContext(element) @@ -13,13 +16,13 @@ class DI { val existingValue = values[key] if (existingValue != null) return existingValue as T if (type in injectionStack) { - error("Found injection cycle: ${injectionStack.joinToString(" -> ")} -> $type") + error("Found injection cycle: ${formatInjectionStack()} -> $type") } injectionStack.push(type) val value = try { provider.provideWithContext(this, context) } catch (ex: Exception) { - throw RuntimeException("Could not create instance for type $type", ex) + throw RuntimeException("Could not create instance for type $type (in stack ${formatInjectionStack()})", ex) } val cycleCheckCookie = injectionStack.pop() require(cycleCheckCookie == type) { "Unbalanced stack cookie: $cycleCheckCookie != $type" } diff --git a/src/main/kotlin/moe/nea/ledger/utils/di/DIProvider.kt b/src/main/kotlin/moe/nea/ledger/utils/di/DIProvider.kt index b5ce550..bd5b9ef 100644 --- a/src/main/kotlin/moe/nea/ledger/utils/di/DIProvider.kt +++ b/src/main/kotlin/moe/nea/ledger/utils/di/DIProvider.kt @@ -24,6 +24,7 @@ fun interface DIProvider<T : Any> : BaseDIProvider<T, Unit> { ?: clazz.constructors.find { it.parameterCount == 0 } ?: error("Could not find DI injection entrypoint for class $clazz")) as Constructor<out T> + // TODO: consider using unsafe init to inject the parameters *before* calling the constructor return DIProvider { di -> val typArgs = cons.parameters.map { di.provide(it.type, it) |