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

scopes.mddocs/

Scope Management

Scoped dependency lifecycles for managing instances with controlled lifecycles and isolation.

Capabilities

Scope Creation

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): Scope

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

Scope Retrieval

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

Scope Class

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

Scope Linking

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)

Scope Callbacks

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 Definitions

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

docs

application.md

components.md

dependency-injection.md

global-context.md

index.md

modules.md

scopes.md

tile.json