All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.salomonbrys.kodein.Injector.kt Maven / Gradle / Ivy

package com.github.salomonbrys.kodein

import java.lang.reflect.Type
import java.util.*

@Suppress("unused")
class KodeinInjector() : KodeinInjectedBase {

    override val injector = this

    class UninjectedException : RuntimeException("Value has not been injected")

    private val _list = LinkedList>()

    private var _kodein: Kodein? = null

    private var _onInjecteds = ArrayList<(Kodein) -> Unit>()

    fun onInjected(cb: (Kodein) -> Unit) {
        val k1 = _kodein
        if (k1 != null)
            cb(k1)
        else
            synchronized(this@KodeinInjector) {
                val k2 = _kodein
                if (k2 != null)
                    cb(k2)
                else
                    _onInjecteds.add(cb)
            }
    }

    private fun  _register(injected: InjectedProperty): InjectedProperty {
        val k1 = _kodein
        if (k1 != null)
            injected._inject(k1.container)
        else
            synchronized(this@KodeinInjector) {
                val k2 = _kodein
                if (k2 != null)
                    injected._inject(k2.container)
                else
                    _list.add(injected)
            }

        return injected
    }

    @Suppress("UNCHECKED_CAST", "CAST_NEVER_SUCCEEDS")
    inner class TInjector {

        @JvmOverloads
        fun factory(argType: Type, type: Type, tag: Any? = null): InjectedProperty<(Any?) -> Any> = _register(InjectedFactoryProperty(Kodein.Key(Kodein.Bind(type, tag), argType)))

        @JvmOverloads
        fun  factory(argType: Type, type: Class, tag: Any? = null): InjectedProperty<(Any?) -> T> = factory(argType, type as Type, tag) as InjectedProperty<(Any?) -> T>

        @JvmOverloads
        fun  factory(argType: Type, type: TypeToken, tag: Any? = null): InjectedProperty<(Any?) -> T> = factory(argType, type.type, tag) as InjectedProperty<(Any?) -> T>

        @JvmOverloads
        fun  factory(argType: Class, type: Type, tag: Any? = null): InjectedProperty<(A) -> Any> = factory(argType as Type, type, tag)

        @JvmOverloads
        fun  factory(argType: Class, type: Class, tag: Any? = null): InjectedProperty<(A) -> T> = factory(argType as Type, type as Type, tag) as InjectedProperty<(A) -> T>

        @JvmOverloads
        fun  factory(argType: Class, type: TypeToken, tag: Any? = null): InjectedProperty<(A) -> T> = factory(argType as Type, type.type, tag) as InjectedProperty<(A) -> T>

        @JvmOverloads
        fun  factory(argType: TypeToken, type: Type, tag: Any? = null): InjectedProperty<(A) -> Any> = factory(argType.type, type, tag)

        @JvmOverloads
        fun  factory(argType: TypeToken, type: Class, tag: Any? = null): InjectedProperty<(A) -> T> = factory(argType.type, type as Type, tag) as InjectedProperty<(A) -> T>

        @JvmOverloads
        fun  factory(argType: TypeToken, type: TypeToken, tag: Any? = null): InjectedProperty<(A) -> T> = factory(argType.type, type.type, tag) as InjectedProperty<(A) -> T>



        @JvmOverloads
        fun factoryOrNull(argType: Type, type: Type, tag: Any? = null): InjectedProperty<((Any?) -> Any)?> = _register(InjectedNullableFactoryProperty(Kodein.Key(Kodein.Bind(type, tag), argType)))

        @JvmOverloads
        fun  factoryOrNull(argType: Type, type: Class, tag: Any? = null): InjectedProperty<((Any?) -> T)?> = factoryOrNull(argType, type as Type, tag) as InjectedProperty<((Any?) -> T)?>

        @JvmOverloads
        fun  factoryOrNull(argType: Type, type: TypeToken, tag: Any? = null): InjectedProperty<((Any?) -> T)?> = factoryOrNull(argType, type.type, tag) as InjectedProperty<((Any?) -> T)?>

        @JvmOverloads
        fun  factoryOrNull(argType: Class, type: Type, tag: Any? = null): InjectedProperty<((A) -> Any)?> = factoryOrNull(argType as Type, type, tag)

        @JvmOverloads
        fun  factoryOrNull(argType: Class, type: Class, tag: Any? = null): InjectedProperty<((A) -> T)?> = factoryOrNull(argType as Type, type as Type, tag) as InjectedProperty<((A) -> T)?>

        @JvmOverloads
        fun  factoryOrNull(argType: Class, type: TypeToken, tag: Any? = null): InjectedProperty<((A) -> T)?> = factoryOrNull(argType as Type, type.type, tag) as InjectedProperty<((A) -> T)?>

        @JvmOverloads
        fun  factoryOrNull(argType: TypeToken, type: Type, tag: Any? = null): InjectedProperty<((A) -> Any)?> = factoryOrNull(argType.type, type, tag)

        @JvmOverloads
        fun  factoryOrNull(argType: TypeToken, type: Class, tag: Any? = null): InjectedProperty<((A) -> T)?> = factoryOrNull(argType.type, type as Type, tag) as InjectedProperty<((A) -> T)?>

        @JvmOverloads
        fun  factoryOrNull(argType: TypeToken, type: TypeToken, tag: Any? = null): InjectedProperty<((A) -> T)?> = factoryOrNull(argType.type, type.type, tag) as InjectedProperty<((A) -> T)?>



        @JvmOverloads
        fun provider(type: Type, tag: Any? = null): InjectedProperty<() -> Any> = _register(InjectedProviderProperty(Kodein.Bind(type, tag)))

        @JvmOverloads
        fun  provider(type: Class, tag: Any? = null): InjectedProperty<() -> T> = provider(type as Type, tag) as InjectedProperty<() -> T>

        @JvmOverloads
        fun  provider(type: TypeToken, tag: Any? = null): InjectedProperty<() -> T> = provider(type.type, tag) as InjectedProperty<() -> T>



        @JvmOverloads
        fun providerOrNull(type: Type, tag: Any? = null): InjectedProperty<(() -> Any)?> = _register(InjectedNullableProviderProperty(Kodein.Bind(type, tag)))

        @JvmOverloads
        fun  providerOrNull(type: Class, tag: Any? = null): InjectedProperty<(() -> T)?> = providerOrNull(type as Type, tag) as InjectedProperty<(() -> T)?>

        @JvmOverloads
        fun  providerOrNull(type: TypeToken, tag: Any? = null): InjectedProperty<(() -> T)?> = providerOrNull(type.type, tag) as InjectedProperty<(() -> T)?>



        @JvmOverloads
        fun instance(type: Type, tag: Any? = null): InjectedProperty = _register(InjectedInstanceProperty(Kodein.Bind(type, tag)))

        @JvmOverloads
        fun  instance(type: Class, tag: Any? = null): InjectedProperty = instance(type as Type, tag) as InjectedProperty

        @JvmOverloads
        fun  instance(type: TypeToken, tag: Any? = null): InjectedProperty = instance(type.type, tag) as InjectedProperty



        fun instanceOrNull(type: Type, tag: Any? = null): InjectedProperty = _register(InjectedNullableInstanceProperty(Kodein.Bind(type, tag)))

        @JvmOverloads
        fun  instanceOrNull(type: Class, tag: Any? = null): InjectedProperty = instanceOrNull(type as Type, tag) as InjectedProperty

        @JvmOverloads
        fun  instanceOrNull(type: TypeToken, tag: Any? = null): InjectedProperty = instanceOrNull(type.type, tag) as InjectedProperty

    }

    val typed = TInjector()

    fun kodein(): Lazy = lazy { _kodein ?: throw KodeinInjector.UninjectedException() }

    fun inject(kodein: Kodein) {
        if (_kodein != null)
            return

        synchronized(this@KodeinInjector) {
            if (_kodein != null)
                return

            _kodein = kodein
        }

        _list.forEach { it._inject(kodein.container) }
        _list.clear()

        _onInjecteds.forEach { it(kodein) }
        _onInjecteds.clear()
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy