Suspending factories: any plans?
milgner opened this issue · 1 comments
milgner commented
I read in TODO.md
that suspending factories would be a major change. I'm wondering whether there are any plans to implement them?
In a project based on Vert.x, where most APIs are asynchronous and called through suspending functions, I'm currently doing the following to construct an object:
typealias DIInit = DI.MainBuilder.() -> Unit
override fun configureDI(): DIInit = {
bind {
provider {
val configRetriever = instance<ConfigRetriever>()
// just calling `runBlocking` here would deadlock the application.
// But when launching through a different dispatcher, it's
// possible to await its result through `runBlocking` afterwards.
val configJob = GlobalScope.async(Dispatchers.IO) { configuration(configRetriever) }
val config = runBlocking { configJob.await() }
RabbitMQClient.create(instance(), config)
}
}
}
private suspend fun configuration(configRetriever: ConfigRetriever): RabbitMQOptions {
val config = configRetriever.config.await()
val rabbitConfig = config.getJsonObject("rabbitmq")
val uri = rabbitConfig.getString("uri")
return RabbitMQOptions().setUri(uri) // detailed configuration omitted for brevity
}
Now I was thinking about just wrapping that in a helper function - but having it built-in would probably be preferable 😅
romainbsl commented
I have been thinking a lot about this lately.
This is maybe dangerous to have suspendable code inside the dependency retrieving mechanism.
I would consider using something like a Deferred type to bind any awaited value / instance.