diff options
Diffstat (limited to 'src/main/kotlin/moe/nea/ledger')
-rw-r--r-- | src/main/kotlin/moe/nea/ledger/utils/di/DI.kt | 78 | ||||
-rw-r--r-- | src/main/kotlin/moe/nea/ledger/utils/di/DIProvider.kt | 52 | ||||
-rw-r--r-- | src/main/kotlin/moe/nea/ledger/utils/di/Inject.kt | 6 |
3 files changed, 0 insertions, 136 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 deleted file mode 100644 index a9061d7..0000000 --- a/src/main/kotlin/moe/nea/ledger/utils/di/DI.kt +++ /dev/null @@ -1,78 +0,0 @@ -package moe.nea.ledger.utils.di - -import java.lang.reflect.AnnotatedElement -import java.util.Collections -import java.util.Stack - -@Suppress("UNCHECKED_CAST") -class DI { - private fun formatInjectionStack() = - injectionStack.joinToString(" -> ") - - fun <T : Any> getProvider(type: Class<T>): BaseDIProvider<T, *> { - val provider = providers[type] as BaseDIProvider<T, *>? - ?: error("Could not find provider for type $type") - return provider - } - - private fun <T : Any, C> internalProvide(type: Class<T>, element: AnnotatedElement? = null): T { - try { - val provider = getProvider(type) as BaseDIProvider<T, C> - val context = if (element == null) provider.createEmptyContext() else provider.createContext(element) - val key = Pair(type, context) - val existingValue = values[key] - if (existingValue != null) return existingValue as T - if (type in injectionStack) { - error("Found injection cycle: ${formatInjectionStack()} -> $type") - } - injectionStack.push(type) - val value = - provider.provideWithContext(this, context) - val cycleCheckCookie = injectionStack.pop() - require(cycleCheckCookie == type) { "Unbalanced stack cookie: $cycleCheckCookie != $type" } - values[key] = value - return value - } catch (ex: Exception) { - throw RuntimeException("Could not create instance for type $type (in stack ${formatInjectionStack()})", ex) - } - } - - fun <T : Any> provide(type: Class<T>, element: AnnotatedElement? = null): T { - return internalProvide<T, Any>(type, element) - } - - inline fun <reified T : Any> provide(): T = provide(T::class.java) - - fun <T : Any> register(type: Class<T>, provider: BaseDIProvider<T, *>) { - providers[type] = provider - } - - fun registerInjectableClasses(vararg type: Class<*>) { - type.forEach { internalRegisterInjectableClass(it) } - } - - private fun <T : Any> internalRegisterInjectableClass(type: Class<T>) { - register(type, DIProvider.fromInjectableClass(type)) - } - - fun instantiateAll() { - providers.keys.forEach { - provide(it, null) - } - } - - fun getAllInstances(): Collection<Any> = - Collections.unmodifiableCollection(values.values) - - fun <T : Any> registerSingleton(value: T) { - register(value.javaClass, DIProvider.singeleton(value)) - } - - private val injectionStack: Stack<Class<*>> = Stack() - private val values = mutableMapOf<Pair<Class<*>, *>, Any>() - private val providers = mutableMapOf<Class<*>, BaseDIProvider<*, *>>() - - init { - registerSingleton(this) - } -}
\ No newline at end of file diff --git a/src/main/kotlin/moe/nea/ledger/utils/di/DIProvider.kt b/src/main/kotlin/moe/nea/ledger/utils/di/DIProvider.kt deleted file mode 100644 index bd5b9ef..0000000 --- a/src/main/kotlin/moe/nea/ledger/utils/di/DIProvider.kt +++ /dev/null @@ -1,52 +0,0 @@ -package moe.nea.ledger.utils.di - -import java.lang.reflect.AnnotatedElement -import java.lang.reflect.Constructor - -fun interface DIProvider<T : Any> : BaseDIProvider<T, Unit> { - override fun provideWithContext(di: DI, context: Unit): T { - return provide(di) - } - - override fun createContext(element: AnnotatedElement) { - } - - override fun createEmptyContext() { - } - - fun provide(di: DI): T - - companion object { - - fun <T : Any> fromInjectableClass(clazz: Class<T>): DIProvider<T> { - @Suppress("UNCHECKED_CAST") - val cons = (clazz.constructors.find { it.getAnnotation(Inject::class.java) != null } - ?: 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) - }.toTypedArray() - val instance = cons.newInstance(*typArgs) - for (it in clazz.fields) { - if (it.getAnnotation(Inject::class.java) == null) continue - it.set(instance, di.provide(it.type, it)) - } - instance - } - } - - fun <T : Any> singeleton(value: T): DIProvider<T> { - return DIProvider { _ -> value } - } - } - -} - -interface BaseDIProvider<T : Any, C> { - fun createContext(element: AnnotatedElement): C - fun provideWithContext(di: DI, context: C): T - fun createEmptyContext(): C -} diff --git a/src/main/kotlin/moe/nea/ledger/utils/di/Inject.kt b/src/main/kotlin/moe/nea/ledger/utils/di/Inject.kt deleted file mode 100644 index a8fdd87..0000000 --- a/src/main/kotlin/moe/nea/ledger/utils/di/Inject.kt +++ /dev/null @@ -1,6 +0,0 @@ -package moe.nea.ledger.utils.di - -@Retention(AnnotationRetention.RUNTIME) -@Target(AnnotationTarget.CONSTRUCTOR, AnnotationTarget.FIELD) -annotation class Inject( -) |