Skip to content

Commit

Permalink
Merge branch '4.0.2' into 4.1.0
Browse files Browse the repository at this point in the history
# Conflicts:
#	examples/gradle/versions.gradle
#	projects/gradle.properties
  • Loading branch information
arnaudgiuliani committed Jan 8, 2025
2 parents fbad1e4 + 67b8150 commit 384d015
Show file tree
Hide file tree
Showing 12 changed files with 110 additions and 101 deletions.
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/Bug_report.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,4 @@ A clear and concise description of what you expected to happen.
[e.g]: `koin-core:3.4.3`

**Snippet or Sample project to help reproduce**
Add a snippet or even a small sample project to hel reproduce your case.
Add a snippet or even a small sample project to help reproduce your case.
2 changes: 2 additions & 0 deletions .github/ISSUE_TEMPLATE/Feature_request.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ about: Suggest an idea for this project

---

If your feature request is a new feature design, please follow [Koin KFIP](https://github.com/InsertKoinIO/KFIP?tab=readme-ov-file) request.

**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

Expand Down
2 changes: 1 addition & 1 deletion examples/androidx-samples/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ dependencies {
implementation "io.insert-koin:koin-core-coroutines"
implementation "io.insert-koin:koin-androidx-workmanager"
implementation "io.insert-koin:koin-androidx-navigation"
implementation "io.insert-koin:koin-androidx-startup"
// implementation "io.insert-koin:koin-androidx-startup"
testImplementation "io.insert-koin:koin-test-junit4"
testImplementation "io.insert-koin:koin-android-test"
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import org.koin.android.ext.koin.androidFileProperties
import org.koin.android.ext.koin.androidLogger
import org.koin.androidx.fragment.koin.fragmentFactory
import org.koin.androidx.workmanager.koin.workManagerFactory
import org.koin.androix.startup.KoinStartup
import org.koin.core.context.GlobalContext.startKoin
import org.koin.core.lazyModules
import org.koin.core.logger.Level
Expand All @@ -22,24 +21,15 @@ import org.koin.mp.KoinPlatform
import org.koin.sample.sandbox.di.allModules


class MainApplication : Application(), KoinStartup {
class MainApplication : Application() {

override fun onKoinStartup() = koinConfiguration {
androidLogger(Level.DEBUG)
androidContext(this@MainApplication)
androidFileProperties()
fragmentFactory()
workManagerFactory()
// lazyModules(allModules, dispatcher = IO)
modules(allModules)
}

// override fun onKoinStartup() : KoinAppDeclaration = {
// override fun onKoinStartup() = koinConfiguration {
// androidLogger(Level.DEBUG)
// androidContext(this@MainApplication)
// androidFileProperties()
// fragmentFactory()
// workManagerFactory()
//// lazyModules(allModules, dispatcher = IO)
// modules(allModules)
// }

Expand Down Expand Up @@ -68,20 +58,20 @@ class MainApplication : Application(), KoinStartup {

startTime = System.currentTimeMillis()

// startKoin {
// androidLogger(Level.DEBUG)
// androidContext(this@MainApplication)
// androidFileProperties()
// fragmentFactory()
// workManagerFactory()
//// lazyModules(allModules, dispatcher = IO)
// modules(allModules)
// }
startKoin {
androidLogger(Level.DEBUG)
androidContext(this@MainApplication)
androidFileProperties()
fragmentFactory()
workManagerFactory()
// lazyModules(allModules, dispatcher = IO)
modules(allModules)
}

//TODO Load/Unload Koin modules scenario cases
cancelPendingWorkManager(this)

KoinPlatform.getKoin().waitAllStartJobs()
// KoinPlatform.getKoin().waitAllStartJobs()
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* Copyright 2017-Present the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.koin.core.error

/**
* Scoep value search for given ScopeId is not found
* @author Arnaud Giuliani
*/
class MissingScopeValueException(msg: String) : Exception(msg)

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package org.koin.core.instance

import org.koin.core.definition.BeanDefinition
import org.koin.core.error.MissingScopeValueException
import org.koin.core.scope.Scope
import org.koin.core.scope.ScopeID
import org.koin.mp.KoinPlatformTools
Expand All @@ -24,11 +25,18 @@ import org.koin.mp.KoinPlatformTools
* Single instance holder
* @author Arnaud Giuliani
*/
class ScopedInstanceFactory<T>(beanDefinition: BeanDefinition<T>) :
class ScopedInstanceFactory<T>(beanDefinition: BeanDefinition<T>, val holdInstance : Boolean = true) :
InstanceFactory<T>(beanDefinition) {

private var values = hashMapOf<ScopeID, T>()

fun size() = values.size

@PublishedApi
internal fun saveValue(id : ScopeID, value : T){
values[id] = value
}

override fun isCreated(context: ResolutionContext?): Boolean = (values[context?.scope?.id] != null)

override fun drop(scope: Scope?) {
Expand All @@ -42,20 +50,20 @@ class ScopedInstanceFactory<T>(beanDefinition: BeanDefinition<T>) :
return if (values[context.scope.id] == null) {
super.create(context)
} else {
values[context.scope.id] ?: error("Scoped instance not found for ${context.scope.id} in $beanDefinition")
values[context.scope.id] ?: throw MissingScopeValueException("Factory.create - Scoped instance not found for ${context.scope.id} in $beanDefinition")
}
}

override fun get(context: ResolutionContext): T {
if (context.scope.scopeQualifier != beanDefinition.scopeQualifier) {
error("Wrong Scope: trying to open instance for ${context.scope.id} in $beanDefinition")
error("Wrong Scope qualifier: trying to open instance for ${context.scope.id} in $beanDefinition")
}
KoinPlatformTools.synchronized(this) {
if (!isCreated(context)) {
values[context.scope.id] = create(context)
if (!isCreated(context) && holdInstance) {
values[context.scope.id] = super.create(context)
}
}
return values[context.scope.id] ?: error("Scoped instance not found for ${context.scope.id} in $beanDefinition")
return values[context.scope.id] ?: throw MissingScopeValueException("Factory.get -Scoped instance not found for ${context.scope.id} in $beanDefinition")
}

override fun dropAll() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,19 @@ package org.koin.core.registry

import org.koin.core.Koin
import org.koin.core.annotation.KoinInternalApi
import org.koin.core.definition.BeanDefinition
import org.koin.core.definition.IndexKey
import org.koin.core.definition.Kind
import org.koin.core.definition._createDefinition
import org.koin.core.definition.indexKey
import org.koin.core.instance.DeclaredScopedInstance
import org.koin.core.instance.ResolutionContext
import org.koin.core.instance.InstanceFactory
import org.koin.core.instance.NoClass
import org.koin.core.instance.ScopedInstanceFactory
import org.koin.core.instance.SingleInstanceFactory
import org.koin.core.module.Module
import org.koin.core.module.overrideError
import org.koin.core.parameter.ParametersHolder
import org.koin.core.qualifier.Qualifier
import org.koin.core.scope.Scope
import org.koin.core.scope.ScopeID
Expand Down Expand Up @@ -114,25 +115,28 @@ class InstanceRegistry(val _koin: Koin) {
@PublishedApi
internal inline fun <reified T> scopeDeclaredInstance(
instance: T,
scopeQualifier: Qualifier,
scopeID: ScopeID,
qualifier: Qualifier? = null,
secondaryTypes: List<KClass<*>> = emptyList(),
allowOverride: Boolean = true,
scopeQualifier: Qualifier,
scopeID: ScopeID,
holdInstance : Boolean
) {
val def = _createDefinition(Kind.Scoped, qualifier, { instance }, secondaryTypes, scopeQualifier)
val indexKey = indexKey(def.primaryType, def.qualifier, def.scopeQualifier)
val existingFactory = instances[indexKey] as? DeclaredScopedInstance<T>
val primaryType = T::class
val indexKey = indexKey(primaryType, qualifier, scopeQualifier)
val existingFactory = instances[indexKey] as? ScopedInstanceFactory<T>
if (existingFactory != null) {
existingFactory.setValue(instance)
existingFactory.saveValue(scopeID, instance)
} else {
val factory = DeclaredScopedInstance(def,scopeID)
val definitionFunction : Scope.(ParametersHolder) -> T = if (!holdInstance) ( { error("Declared definition of type '$primaryType' shouldn't be executed") } ) else ({ instance })
val def: BeanDefinition<T> = _createDefinition(Kind.Scoped, qualifier, definitionFunction, secondaryTypes, scopeQualifier)
val factory = ScopedInstanceFactory(def, holdInstance = holdInstance)
saveMapping(allowOverride, indexKey, factory)
def.secondaryTypes.forEach { clazz ->
val index = indexKey(clazz, def.qualifier, def.scopeQualifier)
saveMapping(allowOverride, index, factory)
}
factory.setValue(instance)
factory.saveValue(scopeID, instance)
}
}

Expand All @@ -156,7 +160,6 @@ class InstanceRegistry(val _koin: Koin) {

internal fun dropScopeInstances(scope: Scope) {
_instances.values.filterIsInstance<ScopedInstanceFactory<*>>().forEach { factory -> factory.drop(scope) }
_instances.values.removeAll { it is DeclaredScopedInstance<*> && it.scopeID == scope.id }
}

internal fun close() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import org.koin.core.Koin
import org.koin.core.annotation.KoinInternalApi
import org.koin.core.error.ClosedScopeException
import org.koin.core.error.MissingPropertyException
import org.koin.core.error.MissingScopeValueException
import org.koin.core.error.NoDefinitionFoundException
import org.koin.core.instance.ResolutionContext
import org.koin.core.logger.Level
Expand Down Expand Up @@ -61,7 +62,6 @@ class Scope(
@KoinInternalApi
private var parameterStack: ThreadLocal<ArrayDeque<ParametersHolder>>? = null


private var _closed: Boolean = false
val logger: Logger get() = _koin.logger

Expand Down Expand Up @@ -182,6 +182,9 @@ class Scope(
} catch (e: NoDefinitionFoundException) {
_koin.logger.debug("* No instance found for type '${clazz.getFullName()}' on scope '${toString()}'")
null
} catch (e: MissingScopeValueException) {
_koin.logger.debug("* No Scoped value found for type '${clazz.getFullName()}' on scope '${toString()}'")
null
}
}

Expand Down Expand Up @@ -394,14 +397,16 @@ class Scope(
qualifier: Qualifier? = null,
secondaryTypes: List<KClass<*>> = emptyList(),
allowOverride: Boolean = true,
holdInstance : Boolean = false
) = KoinPlatformTools.synchronized(this) {
_koin.instanceRegistry.scopeDeclaredInstance(
instance,
scopeQualifier,
id,
qualifier,
secondaryTypes,
allowOverride,
scopeQualifier,
id,
holdInstance = holdInstance
)
}

Expand Down Expand Up @@ -466,10 +471,16 @@ class Scope(
*/
fun close() = KoinPlatformTools.synchronized(this) {
_koin.logger.debug("|- (-) Scope - id:'$id'")
_closed = true

_callbacks.forEach { it.onScopeClose(this) }
_callbacks.clear()

sourceValue = null
_closed = true

parameterStack?.get()?.clear()
parameterStack = null

_koin.scopeRegistry.deleteScope(this)
}

Expand Down
Loading

0 comments on commit 384d015

Please sign in to comment.