kosi-libs/Kodein

Shorthand for trivial singleton declarations

CLOVIS-AI opened this issue · 2 comments

Problem

Currently, we often end up with declarations like this:

bind() from singleton { FooService(instance(), instance(), instance()) }
bind() from singleton { BarService(instance(), instance(), instance(), instance(), instance()) }

This is inconvenient, because each time a parameter is added or removed, the DI module declaration fails to compile.

Proposal

Introduce helpers to generate singletons trivially for any number of arguments (per Kotlin tradition, up to 22):

// 1..3
public inline fun <C : Any, reified T: Any> DI.BindBuilder.WithScope<C>.singleton(ref: RefMaker? = null, sync: Boolean = true, noinline creator: (Any) -> T) = singleton { creator(instance()) }
public inline fun <C : Any, reified T: Any> DI.BindBuilder.WithScope<C>.singleton(ref: RefMaker? = null, sync: Boolean = true, noinline creator: (Any, Any) -> T) = singleton { creator(instance(), instance()) }
public inline fun <C : Any, reified T: Any> DI.BindBuilder.WithScope<C>.singleton(ref: RefMaker? = null, sync: Boolean = true, noinline creator: (Any, Any, Any) -> T) = singleton { creator(instance(), instance(), instance()) }

// Usage
bind() from singleton(::FooService)
bind() from singleton(::BarService)

This way, adding or removing arguments does not make the CI module stop compiling.

In fact there is already something for this use case. Maybe the documentation is not that easy to find.
https://kosi-libs.org/kodein/7.19/core/bindings.html#_transitive_dependencies under the "tips" section.

val di = DI {
    bindSingletonOf(::FooService)
    // OR
    bindProviderOf(::FooService)
}

This is ok for a range from 0 to 10 constructor parameters.

Thanks, that's exactly what I was searching for. Have a good day :)