I'm designing an application that needs to support different feature sets in different deployments. I would like to build it in such a way that different feature implementations would be packaged into different jars. Depending on the actual jars in the classpath, respective features would be automatically discovered and activated by the microkernel.
I am looking to use Koin as the microkernel framework for the features autodiscovery. I like the fact it is very lightweight, native to Kotlin, and offers a great support for configuration and dependency management.
However, there does not seem to be support in Koin for modules autodiscovery via the classpath, and I wonder if I am missing something and there is a way to have modules automatically picked up?
I'm going to post my own 'pragmatic' solution which does not seem particularly Kotlin-esque, so would welcome welcome suggestions for better way of doing this!
The design I'm using is a classic for Java and relies on java.util.ServiceLoader. Each jar will have a file in /META-INF/services
, which will contain a name of a class implementing ModuleProvider interface for that jar. The interface is defined as follows:
interface ModuleProvider {
fun buildModule(): org.koin.core.module.Module
}
My microkernel bootstrapping routine now looks like the following:
fun main() {
val app = startKoin {
environmentProperties() // allow system properties to be injected
modules(ServiceLoader.load(ModuleProvider::class.java).iterator().asSequence().map { it.buildModule() }.toList())
}
// rest of bootstrap
}
This works, but I can't help thinking that there must be a more elegant way, because surely I am not the only one with the need for module autodiscovery. Would appreciate suggestions!