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.

Example creating a set of 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:

  • Use different binding types (such as provider or singleton) in the same set.

  • Add bindings to the same set in different modules if the set has been declared first.

Example creating a set of 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.

Example creating a set of 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:

Example retrieving set of 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.

Example retrieving set of 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:

Example of the type alias for a map multi-binding as Map<String, Configuration>.
typealias ConfigurationEntry = Pair<String, Configuration>
typealias ConfigurationEntries = Set<ConfigurationEntry>

Then, bind with keys:

Example binding as in a map multibinding.
val di = DI {
    bindSet<ConfigurationEntry> {
        add { singleton { "foo" to FooConfiguration() } }
        add { provider { "bar" to BarConfiguration() } }
    }
}

Finally, retrieve the map:

Example retrieving a map multibinding.
val configurations by di.instance<ConfigurationEntries>().toMap()