koin icon indicating copy to clipboard operation
koin copied to clipboard

Using bind with generic interfaces does not work correctry

Open shmaltorhbooks opened this issue 8 months ago • 3 comments

Describe the bug When I trying to bind multiple instances to different generic interfaces I<T>, koin returns all instances of I ignoring generic type <T>

Koin module and version: koin-core:3.5.6

Snippet or Sample project to help reproduce

interface SomeHandler<T> {
    fun handle(value: T)
}

class StringsHandler: SomeHandler<String> {
    override fun handle(value: String) = println(value)
}

class LocalDateTimeHandler: SomeHandler<LocalDateTime> {
    override fun handle(value: LocalDateTime) = println(value.format(DateTimeFormatter.ISO_DATE_TIME))
}
import org.koin.core.module.dsl.singleOf
import org.koin.dsl.koinApplication
import org.koin.dsl.module
import org.koin.core.module.dsl.bind
import java.time.LocalDateTime
import kotlin.test.assertTrue
import kotlin.test.*

class ConstructorDLSBindingTest {
    @Test
    fun test_bind_with_generic_interface() {
        val koin = koinApplication {
            modules(module {
                singleOf(::StringsHandler) { bind<SomeHandler<String>>() }
                singleOf(::LocalDateTimeHandler) { bind<SomeHandler<LocalDateTime>>() }
            })
        }.koin

        val textHandlers: List<SomeHandler<String>> = koin.getAll<SomeHandler<String>>()
        val timeHandlers: List<SomeHandler<LocalDateTime>> = koin.getAll<SomeHandler<LocalDateTime>>()

        // fail, actual size is 2
        assertTrue(textHandlers.size == 1)
        // this will throw ClassCastException
        // java.lang.String cannot be cast to java.time.LocalDateTime
        textHandlers.map { it.handle("test") }


        // the same, size == 2, ClassCastException java.time.LocalDateTime cannot be cast to java.lang.String
        assertTrue(timeHandlers.size == 1)
        timeHandlers.map { it.handle(LocalDateTime.now()) }
    }
}

shmaltorhbooks avatar May 25 '24 16:05 shmaltorhbooks