Core dependency injection framework for Kotlin Multiplatform projects targeting WebAssembly JavaScript environments
—
Scoped dependency lifecycles for managing instances with controlled lifecycles and isolation.
Create and manage scoped containers for isolated dependency lifecycles.
/**
* Create a new scope with qualifier and optional source
* @param scopeId - Unique identifier for the scope
* @param qualifier - Scope qualifier defining the scope type
* @param source - Optional source object associated with the scope
* @param scopeArchetype - Optional scope archetype for additional typing
* @return New Scope instance
*/
fun Koin.createScope(scopeId: ScopeID, qualifier: Qualifier, source: Any? = null, scopeArchetype: TypeQualifier? = null): Scope
/**
* Create a new scope with type qualifier
* @param scopeId - Unique identifier for the scope
* @param source - Optional source object associated with the scope
* @param scopeArchetype - Optional scope archetype for additional typing
* @return New Scope instance
*/
inline fun <reified T : Any> Koin.createScope(scopeId: ScopeID, source: Any? = null, scopeArchetype: TypeQualifier? = null): Scope
/**
* Create a new scope with generated ID
* @param scopeId - Unique identifier for the scope (default: generated)
* @return New Scope instance
*/
inline fun <reified T : Any> Koin.createScope(scopeId: ScopeID = KoinPlatformTools.generateId()): Scope
/**
* Create a scope for a KoinScopeComponent
* @param t - Component to create scope for
* @return New Scope instance associated with the component
*/
fun <T : KoinScopeComponent> Koin.createScope(t: T): ScopeUsage Examples:
import org.koin.core.context.startKoin
import org.koin.core.qualifier.named
import org.koin.dsl.module
// Define scoped services
class RequestContext
class UserSession(val userId: String)
class RequestProcessor(private val context: RequestContext, private val session: UserSession)
// Module with scoped definitions
val webModule = module {
scope(named("request")) {
scoped { RequestContext() }
factory { (userId: String) -> UserSession(userId) }
scoped { RequestProcessor(get(), get()) }
}
}
startKoin { modules(webModule) }
// Create scopes
val requestScope = koin.createScope("req-123", named("request"))
val typedScope = koin.createScope<RequestScope>("req-456")
// Use scoped dependencies
val processor = requestScope.get<RequestProcessor> { parametersOf("user-789") }Get existing scopes or create them if they don't exist.
/**
* Get or create a scope with the given ID and qualifier
* @param scopeId - Scope identifier
* @param qualifier - Scope qualifier
* @param source - Optional source object
* @return Existing scope or new scope if not found
*/
fun Koin.getOrCreateScope(scopeId: ScopeID, qualifier: Qualifier, source: Any? = null): Scope
/**
* Get or create a scope with type qualifier
* @param scopeId - Scope identifier
* @return Existing scope or new scope if not found
*/
inline fun <reified T : Any> Koin.getOrCreateScope(scopeId: ScopeID): Scope
/**
* Get an existing scope by ID
* @param scopeId - Scope identifier
* @return Existing scope
* @throws ScopeNotCreatedException if scope doesn't exist
*/
fun Koin.getScope(scopeId: ScopeID): Scope
/**
* Get an existing scope by ID or null if not found
* @param scopeId - Scope identifier
* @return Existing scope or null
*/
fun Koin.getScopeOrNull(scopeId: ScopeID): Scope?
/**
* Delete a scope and close all its instances
* @param scopeId - Scope identifier to delete
*/
fun Koin.deleteScope(scopeId: ScopeID)Usage Examples:
// Get or create scope
val scope = koin.getOrCreateScope("session-123", named("user-session"))
// Get existing scope safely
val existingScope = koin.getScopeOrNull("session-123")
if (existingScope != null) {
val userService = existingScope.get<UserService>()
}
// Get existing scope (throws if not found)
try {
val scope = koin.getScope("session-123")
// Use scope...
} catch (e: ScopeNotCreatedException) {
println("Scope not found")
}
// Clean up scope when done
koin.deleteScope("session-123")Container for scoped dependency injection with lifecycle management.
class Scope {
/** Qualifier identifying the scope type */
val scopeQualifier: Qualifier
/** Unique identifier for this scope instance */
val id: ScopeID
/** Whether this is the root scope */
val isRoot: Boolean
/** Optional scope archetype for additional typing */
val scopeArchetype: TypeQualifier?
/** Whether this scope has been closed */
val closed: Boolean
/**
* Get a dependency from this scope
* @param qualifier - Optional qualifier
* @param parameters - Optional parameters
* @return Instance from this scope or parent scopes
*/
inline fun <reified T : Any> get(qualifier: Qualifier? = null, noinline parameters: ParametersDefinition? = null): T
/**
* Get a dependency from this scope or null if not found
* @param qualifier - Optional qualifier
* @param parameters - Optional parameters
* @return Instance from this scope or null
*/
inline fun <reified T : Any> getOrNull(qualifier: Qualifier? = null, noinline parameters: ParametersDefinition? = null): T?
/**
* Get a dependency by class from this scope
* @param clazz - Class type to resolve
* @param qualifier - Optional qualifier
* @param parameters - Optional parameters
* @return Instance from this scope
*/
fun <T> get(clazz: KClass<*>, qualifier: Qualifier? = null, parameters: ParametersDefinition? = null): T
/**
* Get a dependency by class from this scope or null if not found
* @param clazz - Class type to resolve
* @param qualifier - Optional qualifier
* @param parameters - Optional parameters
* @return Instance from this scope or null
*/
fun <T> getOrNull(clazz: KClass<*>, qualifier: Qualifier? = null, parameters: ParametersDefinition? = null): T?
/**
* Get lazy dependency from this scope
* @param qualifier - Optional qualifier
* @param mode - Thread safety mode
* @param parameters - Optional parameters
* @return Lazy delegate for the dependency
*/
inline fun <reified T : Any> inject(qualifier: Qualifier? = null, mode: LazyThreadSafetyMode = LazyThreadSafetyMode.SYNCHRONIZED, noinline parameters: ParametersDefinition? = null): Lazy<T>
/**
* Get lazy optional dependency from this scope
* @param qualifier - Optional qualifier
* @param mode - Thread safety mode
* @param parameters - Optional parameters
* @return Lazy delegate for the optional dependency
*/
inline fun <reified T : Any> injectOrNull(qualifier: Qualifier? = null, mode: LazyThreadSafetyMode = LazyThreadSafetyMode.SYNCHRONIZED, noinline parameters: ParametersDefinition? = null): Lazy<T?>
/**
* Get the source object associated with this scope
* @return Source object or null
*/
inline fun <reified T : Any> getSource(): T?
/**
* Get all instances of a type from this scope
* @return List of all instances of the given type
*/
inline fun <reified T : Any> getAll(): List<T>
/**
* Get all instances of a class from this scope
* @param clazz - Class type to resolve
* @return List of all instances of the given class
*/
fun <T> getAll(clazz: KClass<*>): List<T>
/**
* Link this scope to other scopes for dependency resolution
* @param scopes - Scopes to link to
*/
fun linkTo(vararg scopes: Scope)
/**
* Unlink this scope from other scopes
* @param scopes - Scopes to unlink from
*/
fun unlink(vararg scopes: Scope)
/**
* Declare an instance in this scope at runtime
* @param instance - Instance to declare
* @param qualifier - Optional qualifier
* @param secondaryTypes - Additional types this instance can be resolved as
* @param allowOverride - Whether to allow overriding existing definitions
* @param holdInstance - Whether to hold reference to the instance
*/
inline fun <reified T> declare(instance: T, qualifier: Qualifier? = null, secondaryTypes: List<KClass<*>> = emptyList(), allowOverride: Boolean = true, holdInstance: Boolean = false)
/**
* Register a callback for scope lifecycle events
* @param callback - Callback to register
*/
fun registerCallback(callback: ScopeCallback)
/**
* Close this scope and cleanup all instances
*/
fun close()
/**
* Get the parent Koin container
* @return Parent Koin instance
*/
fun getKoin(): Koin
/**
* Get a child scope by ID
* @param scopeID - Child scope identifier
* @return Child scope instance
*/
fun getScope(scopeID: ScopeID): Scope
/**
* Get a property with default value from this scope
* @param key - Property key
* @param defaultValue - Default value if not found
* @return Property value or default
*/
fun <T : Any> getProperty(key: String, defaultValue: T): T
/**
* Get an optional property from this scope
* @param key - Property key
* @return Property value or null
*/
fun <T : Any> getPropertyOrNull(key: String): T?
/**
* Get a property from this scope
* @param key - Property key
* @return Property value
*/
fun <T : Any> getProperty(key: String): T
}Usage Examples:
import org.koin.core.scope.Scope
import org.koin.core.parameter.parametersOf
class WebRequestHandler {
fun handleRequest(requestId: String, userId: String) {
// Create request scope
val requestScope = koin.createScope<RequestScope>(requestId)
try {
// Declare request-specific instances
requestScope.declare(RequestId(requestId))
requestScope.declare(UserId(userId))
// Get scoped dependencies
val requestContext = requestScope.get<RequestContext>()
val userSession = requestScope.get<UserSession>()
val processor = requestScope.get<RequestProcessor>()
// Use lazy injection within scope
val logger: RequestLogger by requestScope.inject()
// Process request
processor.handle(requestContext)
logger.logCompletion()
} finally {
// Always close scope to cleanup resources
requestScope.close()
}
}
}Link scopes together for hierarchical dependency resolution.
/**
* Link this scope to other scopes for dependency resolution fallback
* @param scopes - Variable number of scopes to link to
*/
fun Scope.linkTo(vararg scopes: Scope)
/**
* Unlink this scope from other scopes
* @param scopes - Variable number of scopes to unlink from
*/
fun Scope.unlink(vararg scopes: Scope)Usage Examples:
// Create parent and child scopes
val applicationScope = koin.createScope<ApplicationScope>("app")
val userSessionScope = koin.createScope<UserSessionScope>("session-123")
val requestScope = koin.createScope<RequestScope>("request-456")
// Link scopes in hierarchy
requestScope.linkTo(userSessionScope, applicationScope)
userSessionScope.linkTo(applicationScope)
// Dependencies will be resolved from child -> parent
// 1. First check requestScope
// 2. Then check userSessionScope
// 3. Finally check applicationScope
val service = requestScope.get<SomeService>() // Resolved from any linked scope
// Unlink when scope relationships change
requestScope.unlink(userSessionScope)Register callbacks for scope lifecycle events.
/**
* Interface for scope lifecycle callbacks
*/
interface ScopeCallback {
/** Called when scope is created */
fun onScopeCreated(qualifier: Qualifier, scope: Scope)
/** Called when scope is closed */
fun onScopeClosed(qualifier: Qualifier, scope: Scope)
}
/**
* Register a callback for scope lifecycle events
* @param callback - Callback to register
*/
fun Scope.registerCallback(callback: ScopeCallback)Usage Examples:
class LoggingScopeCallback : ScopeCallback {
override fun onScopeCreated(qualifier: Qualifier, scope: Scope) {
println("Scope created: ${qualifier.value} - ${scope.id}")
}
override fun onScopeClosed(qualifier: Qualifier, scope: Scope) {
println("Scope closed: ${qualifier.value} - ${scope.id}")
}
}
// Register callback
val scope = koin.createScope<RequestScope>("request-123")
scope.registerCallback(LoggingScopeCallback())
// Callbacks will be invoked during scope lifecycle
scope.close() // Triggers onScopeClosed/**
* Type alias for scope identifiers
*/
typealias ScopeID = String
/**
* Interface for scope lifecycle callbacks
*/
interface ScopeCallback {
fun onScopeCreated(qualifier: Qualifier, scope: Scope)
fun onScopeClosed(qualifier: Qualifier, scope: Scope)
}
/**
* Exception thrown when scope is not found
*/
class ScopeNotCreatedException(scopeId: ScopeID) : RuntimeException("Scope '$scopeId' not created")
/**
* Exception thrown when scope is already created
*/
class ScopeAlreadyCreatedException(scopeId: ScopeID) : RuntimeException("Scope '$scopeId' already created")
/**
* Exception thrown when trying to use a closed scope
*/
class ClosedScopeException(scopeId: ScopeID) : RuntimeException("Scope '$scopeId' is closed")Install with Tessl CLI
npx tessl i tessl/maven-io-insert-koin--koin-core-wasm-js