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)
}
}-
Creating a set binding of
Configuration. -
adds a
Configurationbinding implementation using the convenience method. -
adds a
Configurationbinding and attaches it to the DI container.
|
Note
|
You can:
|
Convenience Methods
Kodein-DI provides two types of convenience methods for adding bindings to sets:
add* Methods
The add* methods add bindings only to the set:
val di = DI {
bindSet<Configuration> {
addSingleton { FooConfiguration() } // (1)
addProvider { BarConfiguration() } // (2)
addInstance(existingConfig) // (3)
}
}-
Adds a singleton binding to the set (equivalent to
add { singleton { FooConfiguration() } }). -
Adds a provider binding to the set (equivalent to
add { provider { BarConfiguration() } }). -
Adds an instance binding to the set (equivalent to
add { instance(existingConfig) }).
bind* Methods
The bind* methods add bindings to both the set AND the DI container, allowing retrieval by tag:
val di = DI {
bindSet<Configuration> {
bindSingleton(tag = "foo") { FooConfiguration() } // (1)
bindProvider(tag = "bar") { BarConfiguration() } // (2)
bindInstance(tag = "existing", instance = existingConfig) // (3)
}
}
// Retrieve from set
val allConfigs: Set<Configuration> by di.instance()
// Also retrieve individually by tag
val fooConfig: Configuration by di.instance(tag = "foo")
val barConfig: Configuration by di.instance(tag = "bar")-
Adds a singleton to the set AND registers it in the container with tag "foo".
-
Adds a provider to the set AND registers it in the container with tag "bar".
-
Adds an instance to the set AND registers it in the container with tag "existing".
|
Tip
|
Use |
Configuration bindings and populates it from modules.val module1 by DI.Module {
inBindSet<Configuration> {
addProvider { FooConfiguration() } // (2)
addSingleton { BarConfiguration() } // (2)
}
}
val di = DI {
bindSet<Configuration>() // (1)
importAll(module1)
}-
Creating a set binding of
Configuration. -
add multiple
Configurationbinding implementation using convenience methods.
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 with add* methods.val di = DI {
bindArgSet<Query, Result> { // (1)
addFactory { q: Query -> Foo.query(q) } // (2)
addMultiton { q: Query -> Bar.query(q) } // (3)
}
}-
Creating an argument set binding of
Resultfor arguments of typeQuery. -
Adds a factory binding using convenience method (equivalent to
add { factory { q: Query → Foo.query(q) } }). -
Adds a multiton binding using convenience method (equivalent to
add { multiton { q: Query → Bar.query(q) } }).
val di = DI {
bindArgSet<Query, Result> {
bindFactory(tag = "foo") { q: Query -> Foo.query(q) } // (1)
bindMultiton(tag = "bar") { q: Query -> Bar.query(q) } // (2)
}
}
// Retrieve from set
val results: Set<Result> by di.instance(arg = Query("SELECT * FROM USER;"))
// Also retrieve individually by tag
val fooFactory: (Query) -> Result by di.factory(tag = "foo")
val barMultiton: (Query) -> Result by di.factory(tag = "bar")-
Adds a factory to the set AND registers it in the container with tag "foo".
-
Adds a multiton to the set AND registers it in the container with tag "bar".
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()