Core dependency injection framework for Kotlin Multiplatform projects targeting WebAssembly JavaScript environments
—
Application-wide dependency management with convenient global functions for common operations.
Global functions for starting and stopping the Koin application.
/**
* Start a global Koin application with an existing KoinApplication
* @param koinApplication - Pre-configured KoinApplication instance
* @return The started KoinApplication
*/
fun startKoin(koinApplication: KoinApplication): KoinApplication
/**
* Start a global Koin application with DSL configuration
* @param appDeclaration - DSL configuration block
* @return The started KoinApplication
*/
fun startKoin(appDeclaration: KoinAppDeclaration): KoinApplication
/**
* Stop the global Koin application and cleanup all resources
*/
fun stopKoin()Usage Examples:
import org.koin.core.context.startKoin
import org.koin.core.context.stopKoin
import org.koin.dsl.module
// Define application modules
val networkModule = module {
single { HttpClient() }
single { ApiService(get()) }
}
val dataModule = module {
single { UserRepository(get()) }
single { ConfigService() }
}
// Start Koin with DSL
startKoin {
modules(networkModule, dataModule)
printLogger()
properties(mapOf(
"api.baseUrl" to "https://api.example.com",
"app.version" to "1.0.0"
))
}
// Application code can now use global Koin...
// Stop Koin when application shuts down
Runtime.getRuntime().addShutdownHook(Thread {
stopKoin()
})Global functions for loading and unloading modules at runtime.
/**
* Load a single module into the global Koin context
* @param module - Module to load
*/
fun loadKoinModules(module: Module)
/**
* Load multiple modules into the global Koin context
* @param modules - List of modules to load
*/
fun loadKoinModules(modules: List<Module>)
/**
* Unload a single module from the global Koin context
* @param module - Module to unload
*/
fun unloadKoinModules(module: Module)
/**
* Unload multiple modules from the global Koin context
* @param modules - List of modules to unload
*/
fun unloadKoinModules(modules: List<Module>)Usage Examples:
import org.koin.core.context.*
import org.koin.dsl.module
// Base application modules
val coreModule = module {
single { DatabaseClient() }
single { ConfigService() }
}
val apiModule = module {
single { ApiClient(get<ConfigService>().apiUrl) }
}
// Start with core modules
startKoin {
modules(coreModule)
}
// Load additional modules based on environment
val environment = System.getProperty("app.environment", "production")
when (environment) {
"development" -> {
val devModule = module {
single<Logger> { ConsoleLogger() }
single { MockApiService() }
}
loadKoinModules(devModule)
}
"test" -> {
val testModule = module {
single<Logger> { TestLogger() }
single { MockDatabaseClient() }
}
loadKoinModules(testModule)
}
else -> {
val prodModule = module {
single<Logger> { FileLogger("/var/log/app.log") }
}
loadKoinModules(listOf(apiModule, prodModule))
}
}
// Later, unload test modules when switching environments
if (environment == "test") {
unloadKoinModules(testModule)
loadKoinModules(apiModule)
}Direct access to the global Koin container for dependency resolution.
/**
* Get the global Koin instance
* @return Global Koin container
* @throws KoinApplicationNotStartedException if Koin hasn't been started
*/
fun GlobalContext.get(): Koin
/**
* Get the global Koin instance or null if not started
* @return Global Koin container or null
*/
fun GlobalContext.getOrNull(): Koin?Usage Examples:
import org.koin.core.context.GlobalContext
// Access global Koin directly
val koin = GlobalContext.get()
val userService = koin.get<UserService>()
// Safe access to global Koin
val koinOrNull = GlobalContext.getOrNull()
if (koinOrNull != null) {
val configService = koinOrNull.get<ConfigService>()
println("App version: ${configService.getVersion()}")
} else {
println("Koin not started yet")
}
// Use in utility functions
object ServiceLocator {
fun getUserService(): UserService? {
return GlobalContext.getOrNull()?.getOrNull<UserService>()
}
fun getConfigValue(key: String, default: String = ""): String {
return GlobalContext.getOrNull()?.getProperty(key, default) ?: default
}
}
// Usage
val userService = ServiceLocator.getUserService()
val dbUrl = ServiceLocator.getConfigValue("db.url", "localhost:5432")Common patterns for using global context effectively.
Application Bootstrap Pattern:
class Application {
companion object {
fun start() {
startKoin {
modules(getAllModules())
printLogger(Level.INFO)
properties(loadProperties())
}
println("Application started with Koin")
}
fun stop() {
println("Shutting down application...")
stopKoin()
println("Application stopped")
}
private fun getAllModules(): List<Module> {
return listOf(
coreModule,
serviceModule,
repositoryModule,
controllerModule
)
}
private fun loadProperties(): Map<String, Any> {
return mapOf(
"app.name" to "MyApp",
"app.version" to "1.0.0",
"db.url" to (System.getenv("DB_URL") ?: "localhost:5432")
)
}
}
}
// Usage
fun main() {
Application.start()
// Application logic...
Runtime.getRuntime().addShutdownHook(Thread {
Application.stop()
})
}Feature Toggle Pattern:
object FeatureManager {
private val featureModules = mutableMapOf<String, Module>()
fun registerFeature(name: String, module: Module) {
featureModules[name] = module
}
fun enableFeature(name: String) {
featureModules[name]?.let { module ->
loadKoinModules(module)
println("Enabled feature: $name")
}
}
fun disableFeature(name: String) {
featureModules[name]?.let { module ->
unloadKoinModules(module)
println("Disabled feature: $name")
}
}
fun isFeatureEnabled(name: String): Boolean {
return featureModules[name]?.isLoaded == true
}
}
// Register features
val analyticsModule = module {
single { AnalyticsService() }
single { EventTracker() }
}
val experimentModule = module {
single { ExperimentService() }
single { ABTestManager() }
}
FeatureManager.registerFeature("analytics", analyticsModule)
FeatureManager.registerFeature("experiments", experimentModule)
// Enable features based on configuration
val enabledFeatures = getConfigValue("enabled.features", "").split(",")
enabledFeatures.forEach { feature ->
FeatureManager.enableFeature(feature.trim())
}Environment-Specific Configuration Pattern:
object EnvironmentConfig {
fun configureForEnvironment(env: String) {
when (env.lowercase()) {
"development" -> configureDevelopment()
"staging" -> configureStaging()
"production" -> configureProduction()
else -> throw IllegalArgumentException("Unknown environment: $env")
}
}
private fun configureDevelopment() {
val devModule = module {
single<Logger> { ConsoleLogger(Level.DEBUG) }
single<DatabaseClient> { H2DatabaseClient() }
single<ApiClient> { MockApiClient() }
}
loadKoinModules(devModule)
}
private fun configureStaging() {
val stagingModule = module {
single<Logger> { FileLogger("staging.log", Level.INFO) }
single<DatabaseClient> { PostgresDatabaseClient(getProperty("staging.db.url")) }
single<ApiClient> { HttpApiClient(getProperty("staging.api.url")) }
}
loadKoinModules(stagingModule)
}
private fun configureProduction() {
val prodModule = module {
single<Logger> { CloudLogger(Level.WARN) }
single<DatabaseClient> { PostgresDatabaseClient(getProperty("prod.db.url")) }
single<ApiClient> { HttpApiClient(getProperty("prod.api.url")) }
}
loadKoinModules(prodModule)
}
}
// Usage in application startup
fun main() {
startKoin {
modules(coreModule)
}
val environment = System.getenv("APP_ENV") ?: "development"
EnvironmentConfig.configureForEnvironment(environment)
// Application runs with environment-specific configuration
}/**
* Interface for global context implementations
*/
interface KoinContext {
fun get(): Koin
fun getOrNull(): Koin?
fun stopKoin()
fun startKoin(koinApplication: KoinApplication): KoinApplication
fun startKoin(appDeclaration: KoinAppDeclaration): KoinApplication
fun loadKoinModules(module: Module, createEagerInstances: Boolean = false)
fun loadKoinModules(modules: List<Module>, createEagerInstances: Boolean = false)
fun unloadKoinModules(module: Module)
fun unloadKoinModules(modules: List<Module>)
}
/**
* Exception thrown when trying to access Koin before it's started
*/
class KoinApplicationNotStartedException : RuntimeException("KoinApplication has not been started")
/**
* Exception thrown when trying to start Koin when it's already started
*/
class KoinApplicationAlreadyStartedException : RuntimeException("KoinApplication has already been started")Install with Tessl CLI
npx tessl i tessl/maven-io-insert-koin--koin-core-wasm-js