hello, is there any DI framework with auto-injecti...
# ktor
a
hello, is there any DI framework with auto-injection? I feel like Koin method using
by inject<T>()
all the time it's too verbose in ktor 2.X.X I had this function with Kodein:
Copy code
routing {
    post("sign-up", executeInvoke<SignUp>())
}

inline fun <reified T : Handler> executeInvoke(): suspend PipelineContext<Unit, ApplicationCall>.(Unit) -> Unit = {
    val handler by closestDI().instance<T>()
    handler(this.call)
}
but I can't make it work with Ktor 3.X.X
a
Koin annotations lets you achieve this somewhat
šŸ‘ 1
r
That is a service locator pattern which couples your code to the framework. Can you instead inject a factory for handlers into the constructor?
a
@rocketraman can you show an example?
r
Unless I'm missing something in your requirements, its pretty trivial. Might be something like this without any DI at all -- but you'd probably want to create the handler map via DI:
Copy code
fun main() {
  // the map could come from DI
  val handlerFactory = HandlerFactory(
    mapOf(
      HelloHandler::class to HelloHandler(),
    )
  )
  Server(handlerFactory).start()
}

class Server(private val handlerFactory: HandlerFactory) {
  fun start() {
    embeddedServer(Netty, port = 8080, host = "0.0.0.0", module = { module(handlerFactory) })
      .start(wait = true)
  }
}

class HandlerFactory(val handlers: Map<KClass<out Handler>, Handler>) {
  inline fun <reified T : Handler> handlerOf(): Handler {
    return handlers[T::class] ?: throw IllegalArgumentException("No handler found for ${T::class}")
  }
}

fun Application.module(handlerFactory: HandlerFactory) {
  configureRouting(handlerFactory)
}

fun Application.configureRouting(handlerFactory: HandlerFactory) {
  routing {
    get("/") {
      handlerFactory.handlerOf<HelloHandler>().invoke(call)
    }
  }
}