Extending plain interfaces
A @DIModule interface may extend any interface, not only @DIModule ones.
Members reachable through a plain supertype are bound exactly like the module’s own members:
interface Taggable {
val id: String
fun tag(): String = "tag:$id"
}
@DIModule
interface TaggableModule : Taggable {
val extra: Int
}
TaggableModule(
id = Binding.value("x1"), (1)
extra = Binding.value(7),
) (2)
| 1 | id comes from Taggable and is abstract, so it must be bound. |
| 2 | tag also comes from Taggable, but it has a default implementation, so its binding is optional. |
This lets a module implement an interface that is defined elsewhere, for example in a library that knows nothing about Inara, and be passed wherever that interface is expected.
Generic supertypes
Type arguments of a generic supertype are substituted in the binding types:
interface Converter<T> {
val default: T
fun convert(input: T): T
}
@DIModule
interface StringConverterModule : Converter<String> {
val prefix: String
}
StringConverterModule(
default = Binding.value(""), (1)
convert = Binding.factory { input -> prefix + input }, (2)
prefix = Binding.value("> "),
)
| 1 | A Binding<StringConverterModule, Unit, String>. |
| 2 | A Binding<StringConverterModule, String, String>. |
Plain supertypes and composition
A plain supertype is not a module, so there is no built instance of it to reuse.
Under @DIModule(composed = true), its members therefore appear as binding parameters of the from-parents builder, next to the members declared on the module itself.