is there a way to retrieve all bindings (like thro...
# kodein
m
is there a way to retrieve all bindings (like through
allInstances()
) regardless of tag? we have an application that has multiple
ServerInterceptor
that gets added to the server right now we have to bind it in basically 2 places 1. where we want to introduce and configure the
ServerInterceptor
implementation 2. in the place where we build the
Server
instance and provide the multiple
ServerInterceptor
it doesn't look like i can have multiple bindings of the same type (even if in separate kodein modules) for example:
Copy code
interface MyInterface

class Impl1 : MyInterface

class Impl2(val s: String) : MyInterface

fun main() {
    val kodein = Kodein {
        constant(tag = "String") with "stringy"
        bind<MyInterface>() with singleton { Impl1() }
        bind<MyInterface>() with singleton { Impl2(instance(tag = "String")) }
    }

    val all = kodein.direct.allInstances<MyInterface>()
    println(all)
}
fails at bin building time with
org.kodein.di.Kodein$OverridingException: Binding bind<MyInterface>() with ? { ? } must not override an existing binding.
adding tags
Copy code
bind<MyInterface>(tag = "1") with singleton { Impl1() }
        bind<MyInterface>(tag = "2") with singleton { Impl2(instance(tag = "String")) }
prints an empty list
[]
i've seen the
inSet()
and
bind() from setBinding<ServerInterceptor>()
, but that feels a bit odd, because then each module needs to also use
inSet()
on the binding what is the best way to handle this if i'm trying to keep the modules separate?
r
doing the following (binding the explicit type, but retrieving all the instances of
MyInterface
), my guess is that if we use tags, their is a wanted extra treatment on it, or its a not known behaviour)
Copy code
interface MyInterface

class Impl1 : MyInterface

class Impl2(val s: String) : MyInterface

fun main() {
    val kodein = Kodein {
        constant(tag = "String") with "stringy"
        bind<Impl1>() with singleton { Impl1() }
        bind<Impl2>() with singleton { Impl2(instance(tag = "String")) }
    }

    val impl1 by kodein.instance<Impl1>()
    println(impl1)
    val impl2 by kodein.instance<Impl2>()
    println(impl2)

    val all by kodein.allInstances<MyInterface>()
    println(all)
}
here is my output:
Copy code
Impl1@1c3a4799
Impl2@26aa12dd
[Impl2@26aa12dd, Impl1@1c3a4799]
o
m
thanks @romainbsl - the explicit type seems like a decent solution
@alan.kleiman i could use set binding, but that forces each binding itself to be "set aware" (which im not 100% sure i want)
r
You're welcome. As @alan.kleiman said you could have use the multi binding in a set, but not using the allInstances function
This would be something like
Copy code
interface MyInterface

class Impl1 : MyInterface

class Impl2(val s: String) : MyInterface

fun main() {
    val kodein = Kodein {
        constant(tag = "String") with "stringy"
        bind() from setBinding<MyInterface>()

        bind<MyInterface>().inSet() with singleton { Impl1() }
        bind<MyInterface>().inSet() with singleton { Impl2(instance(tag = "String")) }
    }

    val configurations: Set<MyInterface> by kodein.instance()
    println(configurations)
}