CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-io-insert-koin--koin-core-jvm

Core dependency injection framework for Kotlin multiplatform applications with DSL-based configuration and type-safe dependency resolution.

Pending
Overview
Eval results
Files

scope-management.mddocs/

Scope Management

Hierarchical scope system for controlling dependency lifecycles and providing isolated dependency contexts for specific application areas. Scopes enable fine-grained resource management and dependency isolation.

Capabilities

Scope Class

Core scope implementation providing isolated dependency container functionality.

/**
 * Scoped dependency container with lifecycle management
 * @param scopeQualifier - Qualifier identifying the scope type
 * @param id - Unique identifier for this scope instance
 * @param isRoot - Whether this is a root scope
 * @param _koin - Associated Koin instance
 */
class Scope(
    val scopeQualifier: Qualifier,
    val id: ScopeID,
    val isRoot: Boolean = false,
    private val _koin: Koin
) {
    /**
     * Whether this scope has been closed
     */
    val closed: Boolean
    
    /**
     * Get associated Koin instance
     * @return Koin instance
     */
    fun getKoin(): Koin
    
    /**
     * Close scope and clean up resources
     */
    fun close()
}

typealias ScopeID = String

Scoped Dependency Injection

Inject dependencies from within a specific scope context.

/**
 * Lazy inject dependency from scope
 * @param qualifier - Optional qualifier to distinguish instances
 * @param mode - Thread safety mode for lazy initialization
 * @param parameters - Optional parameters for dependency creation
 * @return Lazy delegate for the dependency
 */
inline fun <reified T> Scope.inject(
    qualifier: Qualifier? = null,
    mode: LazyThreadSafetyMode = LazyThreadSafetyMode.SYNCHRONIZED,
    noinline parameters: ParametersDefinition? = null
): Lazy<T>

/**
 * Lazy inject dependency from scope with nullable result
 * @param qualifier - Optional qualifier to distinguish instances
 * @param mode - Thread safety mode for lazy initialization
 * @param parameters - Optional parameters for dependency creation
 * @return Lazy delegate for nullable dependency
 */
inline fun <reified T> Scope.injectOrNull(
    qualifier: Qualifier? = null,
    mode: LazyThreadSafetyMode = LazyThreadSafetyMode.SYNCHRONIZED,
    noinline parameters: ParametersDefinition? = null
): Lazy<T?>

/**
 * Get dependency directly from scope
 * @param qualifier - Optional qualifier to distinguish instances
 * @param parameters - Optional parameters for dependency creation
 * @return Resolved dependency instance
 */
inline fun <reified T> Scope.get(
    qualifier: Qualifier? = null,
    noinline parameters: ParametersDefinition? = null
): T

/**
 * Get dependency from scope with nullable result
 * @param qualifier - Optional qualifier to distinguish instances
 * @param parameters - Optional parameters for dependency creation
 * @return Resolved dependency instance or null
 */
inline fun <reified T> Scope.getOrNull(
    qualifier: Qualifier? = null,
    noinline parameters: ParametersDefinition? = null
): T?

/**
 * Get all instances of a type from scope
 * @return List of resolved instances
 */
inline fun <reified T> Scope.getAll(): List<T>

Usage Examples:

import org.koin.core.scope.Scope
import org.koin.core.qualifier.named

class UserFeature {
    private val userScope: Scope = koin.createScope("user-123", named<UserScope>())
    
    fun processUserData() {
        // Lazy injection from scope
        val userSession: UserSession by userScope.inject()
        val userPrefs: UserPreferences by userScope.inject()
        
        // Direct retrieval from scope  
        val userValidator = userScope.get<UserValidator>()
        val userCache = userScope.get<UserCache>(named("memory"))
        
        // Nullable retrieval
        val optionalFeature = userScope.getOrNull<OptionalFeature>()
        
        // Get all validators in scope
        val allValidators = userScope.getAll<Validator>()
        
        // Process with scoped dependencies
        if (userValidator.isValid(userSession.userId)) {
            val data = userPrefs.getData()
            // Process data...
        }
        
        // Clean up scope when done
        userScope.close()
    }
}

Scope Creation & Management

Create and manage scopes through the Koin container.

/**
 * Create new scope in Koin container
 * @param scopeId - Unique identifier for the scope
 * @param qualifier - Scope type qualifier
 * @param source - Optional source object for linking
 * @return New scope instance
 */
fun Koin.createScope(
    scopeId: String,
    qualifier: Qualifier,
    source: Any? = null
): Scope

/**
 * Get existing scope by ID
 * @param scopeId - Scope identifier
 * @return Existing scope instance
 * @throws ScopeNotCreatedException if scope doesn't exist
 */
fun Koin.getScope(scopeId: String): Scope

/**
 * Get existing scope or null
 * @param scopeId - Scope identifier
 * @return Existing scope or null
 */
fun Koin.getScopeOrNull(scopeId: String): Scope?

/**
 * Delete scope by ID
 * @param scopeId - Scope identifier
 */
fun Koin.deleteScope(scopeId: String)

/**
 * Get or create scope
 * @param scopeId - Scope identifier
 * @param qualifier - Scope type qualifier
 * @return Existing or new scope instance
 */
fun Koin.getOrCreateScope(scopeId: String, qualifier: Qualifier): Scope

Usage Examples:

import org.koin.core.context.GlobalContext
import org.koin.core.qualifier.named

class ScopeManager {
    private val koin = GlobalContext.get()
    
    fun createUserScope(userId: String): Scope {
        return koin.createScope(
            scopeId = "user-$userId",
            qualifier = named<UserScope>()
        )
    }
    
    fun getUserScope(userId: String): Scope? {
        return koin.getScopeOrNull("user-$userId")
    }
    
    fun cleanupUserScope(userId: String) {
        koin.deleteScope("user-$userId")
    }
    
    fun processUser(userId: String) {
        // Get or create scope
        val scope = koin.getOrCreateScope("user-$userId", named<UserScope>())
        
        // Use scope
        val userService = scope.get<UserService>()
        userService.processUser(userId)
        
        // Scope remains active for future use
    }
}

Scope Linking & Source Association

Link scopes together and associate scopes with source objects for automatic cleanup.

/**
 * Link this scope to another scope
 * @param scope - Target scope to link to
 */
fun Scope.linkTo(scope: Scope)

/**
 * Unlink this scope from another scope
 * @param scope - Target scope to unlink from
 */
fun Scope.unlink(scope: Scope)

/**
 * Get source object associated with this scope
 * @return Source object or null
 */
fun <T> Scope.getSource(): T?

/**
 * Declare additional instance in scope
 * @param instance - Instance to declare
 * @param qualifier - Optional qualifier
 * @param secondaryTypes - Additional types to bind
 * @param allowOverride - Whether to allow overriding existing declaration
 */
inline fun <reified T> Scope.declare(
    instance: T,
    qualifier: Qualifier? = null,
    secondaryTypes: List<KClass<*>>? = null,
    allowOverride: Boolean = false
)

Usage Examples:

import org.koin.core.scope.Scope
import org.koin.core.qualifier.named

class ActivityScope(private val activity: Activity) {
    private val activityScope: Scope = koin.createScope(
        scopeId = "activity-${activity.hashCode()}",
        qualifier = named<ActivityScope>(),
        source = activity // Link scope to activity lifecycle
    )
    
    private val featureScope: Scope = koin.createScope(
        scopeId = "feature-${activity.hashCode()}",
        qualifier = named<FeatureScope>()
    )
    
    fun initialize() {
        // Link feature scope to activity scope
        featureScope.linkTo(activityScope)
        
        // Declare runtime instance in scope
        activityScope.declare(
            instance = ActivityManager(activity),
            qualifier = named("manager")
        )
        
        // Bind additional types
        activityScope.declare(
            instance = CustomLogger(),
            secondaryTypes = listOf(Logger::class, Closeable::class)
        )
    }
    
    fun getFeatureScope(): Scope = featureScope
    
    fun cleanup() {
        // Unlink scopes
        featureScope.unlink(activityScope)
        
        // Close scopes
        featureScope.close()
        activityScope.close()
        
        // Get source for final cleanup
        val sourceActivity = activityScope.getSource<Activity>()
        sourceActivity?.finish()
    }
}

Scope Properties

Access properties from scope with fallback to parent scopes.

/**
 * Get property value from scope
 * @param key - Property key
 * @param defaultValue - Default value if property not found
 * @return Property value
 */
fun <T> Scope.getProperty(key: String, defaultValue: T): T

/**
 * Get property value from scope
 * @param key - Property key
 * @return Property value or null
 */
fun <T> Scope.getProperty(key: String): T?

/**
 * Set property value in underlying Koin instance
 * @param key - Property key
 * @param value - Property value
 */
fun Scope.setProperty(key: String, value: Any?)

Usage Examples:

import org.koin.core.scope.Scope

class ConfigurableScope(private val scope: Scope) {
    
    fun configure() {
        // Get configuration properties
        val timeout = scope.getProperty("http.timeout", 30)
        val baseUrl = scope.getProperty<String>("api.baseUrl")
        val debug = scope.getProperty("debug.enabled", false)
        
        // Set runtime properties
        scope.setProperty("session.id", generateSessionId())
        scope.setProperty("startup.time", System.currentTimeMillis())
        
        // Use properties for configuration
        val httpClient = scope.get<HttpClient> {
            parametersOf(baseUrl, timeout)
        }
        
        if (debug) {
            scope.get<Logger>().info("Debug mode enabled")
        }
    }
}

Scope Lifecycle Patterns

Request Scope Pattern

import org.koin.core.qualifier.named

// Define request scope
val requestScope = named<RequestScope>()

// Module with request-scoped dependencies
val requestModule = module {
    scope(requestScope) {
        scoped<RequestContext> { RequestContextImpl() }
        scoped<UserSession> { UserSessionImpl(get()) }
        factory<RequestHandler> { RequestHandlerImpl(get(), get()) }
    }
}

// Usage in web controller
class WebController : KoinComponent {
    fun handleRequest(request: HttpRequest): HttpResponse {
        val scope = getKoin().createScope(
            scopeId = request.id,
            qualifier = requestScope
        )
        
        try {
            val handler = scope.get<RequestHandler>()
            return handler.process(request)
        } finally {
            scope.close() // Clean up request resources
        }
    }
}

Feature Module Scoping

import org.koin.core.qualifier.named

class FeatureModule {
    private val featureScope = named<FeatureScope>()
    
    val module = module {
        // Global dependencies
        single<Logger> { LoggerImpl() }
        
        // Feature-scoped dependencies
        scope(featureScope) {
            scoped<FeatureConfig> { FeatureConfigImpl(get()) }
            scoped<FeatureService> { FeatureServiceImpl(get(), get()) }
            factory<FeatureProcessor> { FeatureProcessorImpl(get()) }
        }
    }
    
    fun createFeatureScope(featureId: String): Scope {
        return GlobalContext.get().createScope(
            scopeId = "feature-$featureId",
            qualifier = featureScope
        )
    }
}

Types

typealias ScopeID = String

data class ScopeDefinition(
    val qualifier: Qualifier,
    val definition: Definition<*>,
    val secondaryTypes: List<KClass<*>>,
    val isCreatedAtStart: Boolean
)

class ScopeRegistry {
    fun saveDefinition(scopeQualifier: Qualifier, definition: ScopeDefinition)
    fun getScopeDefinition(scopeQualifier: Qualifier): ScopeDefinition?
}

// Scope-related exceptions
class ScopeNotCreatedException(message: String) : RuntimeException(message)
class ScopeAlreadyCreatedException(message: String) : RuntimeException(message)
class ClosedScopeException(message: String) : RuntimeException(message)

Install with Tessl CLI

npx tessl i tessl/maven-io-insert-koin--koin-core-jvm

docs

application-setup.md

component-integration.md

configuration-logging.md

constructor-reference.md

index.md

java-interop.md

module-definition.md

property-management.md

qualifiers-parameters.md

scope-management.md

tile.json