CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-io-insert-koin--koin-core-wasm-js

Core dependency injection framework for Kotlin Multiplatform projects targeting WebAssembly JavaScript environments

Pending
Overview
Eval results
Files

global-context.mddocs/

Global Context

Application-wide dependency management with convenient global functions for common operations.

Capabilities

Application Lifecycle

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()
})

Dynamic Module Management

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)
}

Global Dependency Access

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")

Global Context Patterns

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
}

Type Definitions

/**
 * 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

docs

application.md

components.md

dependency-injection.md

global-context.md

index.md

modules.md

scopes.md

tile.json