koin: Installing Koin plugin to Ktor (2.0.0-beta-1) is not working

Describe the bug Due to Ktor 2.0.0-beta-1 breaking changes koin install is not working,

To Reproduce Create a sample installation of the plugin. https://ktor.io/docs/creating-custom-plugins.html

fun Application.configureDependencyInjection() {
    install(CustomKoinPlugin) {
        slf4jLogger(Level.ERROR)
        modules(appModule)
    }
}

Expected behavior No error will be encountered in IDE

Ktor dependency injection ktor: 2.0.0-beta-1 koin-ktor: koin-ktor version 3.1.5

Workaround

// Copy from the latest koin code and reimport
val KApplicationStarted = EventDefinition<KoinApplication>()
val KApplicationStopPreparing = EventDefinition<KoinApplication>()
val KApplicationStopped = EventDefinition<KoinApplication>()
// Create a new custom application plugin
internal class CustomKoinPlugin(internal val koinApplication: KoinApplication) {
    // Implements ApplicationPlugin as a companion object.
    companion object Plugin : ApplicationPlugin<ApplicationCallPipeline, KoinApplication, CustomKoinPlugin> {
        // Creates a unique key for the plugin.
        override val key = AttributeKey<CustomKoinPlugin>("CustomKoinPlugin")

        // Code to execute when installing the plugin.
        override fun install(
            pipeline: ApplicationCallPipeline,
            configure: KoinApplication.() -> Unit
        ): CustomKoinPlugin {
            val monitor = pipeline.environment?.monitor
            val koinApplication = startKoin(appDeclaration = configure)
            if (monitor != null) {
                monitor.raise(KApplicationStarted, koinApplication)
                monitor.subscribe(ApplicationStopping) {
                    monitor.raise(KApplicationStopPreparing, koinApplication)
                    stopKoin()
                    monitor.raise(KApplicationStopped, koinApplication)
                }
            } 
            return CustomKoinPlugin(koinApplication)
        }
    }
}
// also copy and reimport the inject extensions

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Reactions: 24
  • Comments: 21 (2 by maintainers)

Most upvoted comments

because koin-ktor will be soon published as stable. Just wait those next days.

@Marek00Malik Have you found a working solution? I have a working solution here: https://gist.github.com/MarkusNowotny/c245b5f493bfdde09d7b9853ef91fb55 This works in my code but I havn’t testet it against ktor and koin. Maybe this helps you

Is there any work on this? Ktor 2.0.0 was released. The workaround is not working any longer.

Ktor 2.0 is in production, Koin is not working. I tried to migrate my project today, everything else worked except Koin. Any updates?

@arnaudgiuliani Hey! Could you plz provide an example for new usage of koin plugin? For me previous approach still is not works for the ktor 2.0

Koin for Ktor 2.0 is now ready in https://github.com/InsertKoinIO/koin-ktor

So I tried @MarkusNowotny solution, indeed it works, at least in tests and basic solutions. This file is what needs to be added, add it as a separate file and use as default Koin plugin.

fun Application.configureKoin() {
    install(Koin) {
        modules = arrayListOf(<your Koin modules>)
    }
}

The module import you are talking about is the one that is from Koin itself.

These are the imports that I’m using.

import io.ktor.events.EventDefinition
import io.ktor.server.application.Application
import io.ktor.server.application.ApplicationCall
import io.ktor.server.application.ApplicationStopped
import io.ktor.server.application.createApplicationPlugin
import io.ktor.server.application.install
import io.ktor.server.routing.Route
import io.ktor.server.routing.Routing
import org.koin.core.Koin
import org.koin.core.KoinApplication
import org.koin.core.context.GlobalContext
import org.koin.core.context.startKoin
import org.koin.core.context.stopKoin
import org.koin.core.module.Module
import org.koin.core.parameter.ParametersDefinition
import org.koin.core.qualifier.Qualifier
import org.koin.dsl.KoinAppDeclaration

for me it didn’t worked( I get bunch of errors in the code 1.

One type argument expected for interface ApplicationPlugin<out TConfiguration : Any>

2

'key' overrides nothing

3

'install' overrides nothing

4

Type mismatch.
Required:
io.ktor.server.application.Plugin<TypeVariable(P), TypeVariable(B), TypeVariable(F)>
Found:
com.example.base.CustomKoinPlugin.Plugin

Please check this repo https://github.com/iamdamjanmiloshevski/betting-doctor-api with a working project available in production. Let me know if you need any help

Pay attention that the modules variable is internal and may not be callable.

I have used it in this way:

fun Application.configureInjection(modules: List<Module> = emptyList()) {
	install(Koin) {
		+module {
			single { environment.config }
			single { log }
		}
		+modules
	}
}

Awesome @iamdamjanmiloshevski! Happy to help 😎

@ceosilvajr, @Marek00Malik thank you both very much, I got it working, just tested. It was the bloody imports that caused the issue. IntelliJ wasn’t picking them up automatically, just copied the imports and the code was ok. The app is running perfectly.

I owe you guys a beer 🍻 or crypto if you want 😎

@iamdamjanmiloshevski you need to use themodules from KoinConfig class and use the list to add your koin module.

I made some modification, I explicitly use org.koin.core.module.Module

class KoinConfig {

    internal var modules: ArrayList<org.koin.core.module.Module> = ArrayList()

    operator fun org.koin.core.module.Module.unaryPlus() {
        modules.add(this)
    }

    operator fun List<org.koin.core.module.Module>.unaryPlus() {
        modules.addAll(this)
    }

}

Then you can do

fun Application.configureKoin() {
    install(KoinPlugin) {
        modules = arrayListOf(
            module{}
        )
    }
}