Multi-binding
Kodein-DI allows multi bindings via a binding set.
In a Set
Binding in a Set
To have multiple bindings in a set, you need to:
-
Declare that you are using a set binding for a particular bound type.
-
Add bindings to the set.
Configuration bindings.val di = DI {
bindSet<Configuration> { (1)
add { provider { FooConfiguration() } } (2)
bind { singleton { BarConfiguration() } } (3)
}
}
| 1 | Creating a set binding of Configuration. |
| 2 | adds a Configuration binding implementation. |
| 3 | adds a Configuration binding and attaches it to the DI container. |
|
You can:
|
Configuration bindings and populates it from modules.val module1 by DI.Module {
inBindSet<Configuration> {
add { provider { FooConfiguration() } } (2)
add { singleton { BarConfiguration() } } (2)
}
}
val di = DI {
bindSet<Configuration>() (1)
importAll(module1)
}
| 1 | Creating a set binding of Configuration. |
| 2 | add multiple Configuration binding implementation. |
You can also bind multiple bindings with arguments (such as factory or multiton) in a set as long as all bindings share the same argument type.
Result bindings.val di = DI {
bindArgSet<Query, Result> { (1)
add { factory { q: Query -> Foo.query(q) } } (2)
add { multiton { q: Query -> Bar.query(q) } } (2)
}
}
| 1 | Creating an argument set binding of Result for arguments of type Query. |
| 2 | Binding multiple Result factories implementations. |
Retrieving from a Set
Note that the type being bound is Set<T>, not T.
Therefore, you need to retrieve a Set:
Configuration.val configurations: Set<Configuration> by di.instance()
To retrieve a Set with argument, thus going through a factory or a multiton, you need to pass the needed argument to the instance function.
Result with Query argument.val result: Set<Result> by di.instance(arg = Query("SELECT * FROM USER;"))
In a map
Kodein-DI does not directly support map multi-binding. However, it is very easy to create a binding map by using a binding set.
First, create the following primitive:
Map<String, Configuration>.typealias ConfigurationEntry = Pair<String, Configuration>
typealias ConfigurationEntries = Set<ConfigurationEntry>
Then, bind with keys:
val di = DI {
bindSet<ConfigurationEntry> {
add { singleton { "foo" to FooConfiguration() } }
add { provider { "bar" to BarConfiguration() } }
}
}
Finally, retrieve the map:
val configurations by di.instance<ConfigurationEntries>().toMap()