aboutsummaryrefslogtreecommitdiff
path: root/src/main/kotlin
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/kotlin')
-rw-r--r--src/main/kotlin/moe/nea/ledger/utils/di/DI.kt78
-rw-r--r--src/main/kotlin/moe/nea/ledger/utils/di/DIProvider.kt52
-rw-r--r--src/main/kotlin/moe/nea/ledger/utils/di/Inject.kt6
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(
-)