Skip to content

Commit

Permalink
Merge pull request #1455 from InsertKoinIO/android_3.2.3
Browse files Browse the repository at this point in the history
Android 3.2.3
  • Loading branch information
arnaudgiuliani committed Oct 18, 2022
2 parents 9bc0315 + c3ede13 commit 3290c04
Show file tree
Hide file tree
Showing 31 changed files with 139 additions and 172 deletions.
1 change: 1 addition & 0 deletions .github/workflows/github-actions-ci-cd-mac.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ jobs:
with:
distribution: "adopt"
java-version: "11"

- name: Validate Gradle Wrapper
uses: gradle/wrapper-validation-action@v1
- name: Cache build tooling
Expand Down
22 changes: 19 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,21 @@ Badges: `[UPDATED]`, `[FIXED]`, `[NEW]`, `[DEPRECATED]`, `[REMOVED]`, `[BREAKIN

# [3.2]()

## [3.2.2](https://github.com/InsertKoinIO/koin/milestone/36?closed=1) - (2022-09-23)
## [android-3.2.3](https://github.com/InsertKoinIO/koin/milestone/38) - 2022-10-18

* `[FIXED]` - Fix Broken Scope API and revert back `AndroidScopeComponent` with related API in `Activity` & `Fragment`. Reworked `activityScope()`, `activityRetainedScope()` and `fragmentScope()`. Removed Deprecations. #1443 #1448
* `[FIXED]` - Fix NavGraph scope resolution #1446


## [3.2.2](https://github.com/InsertKoinIO/koin/milestone/36?closed=1) - 2022-09-23

* `[FIXED]` `[core]` - Java 8 Compat fix
* `[MERGE]` `[test]` - Java 8 Compat fix #1437


## [3.2.1](https://github.com/InsertKoinIO/koin/milestone/36?closed=1) - (2022-09-12)
## [3.2.1](https://github.com/InsertKoinIO/koin/milestone/36?closed=1) - 2022-09-12

* `[NEW]` - Version split for Koin core & Android, to allow sperate track on core & android topics
* `[NEW]` - Version split for Koin core & Android, to allow sperate track on core & android topics (dedicated Github milestones & Git branches/tag)
* `[UPDATED]` `[core]` - lib update - `co.touchlab:stately-concurrency:1.2.2`
* `[UPDATED]` `[android]` - lib update - `androidx.appcompat:appcompat:1.4.2`
* `[MERGE]` - #1409 - Android Test Instrumentation Contribution
Expand All @@ -26,6 +32,16 @@ Badges: `[UPDATED]`, `[FIXED]`, `[NEW]`, `[DEPRECATED]`, `[REMOVED]`, `[BREAKIN
* `[BREAKING]` `[android]` - Deprecate Android Scope API to avoid use lazy delegate API


## [3.2.0]()

The repository has been splitted for the following sub projects.

- `koin-ktor` - https://github.com/InsertKoinIO/koin-ktor
- `koin-androidx-compose` - https://github.com/InsertKoinIO/koin-compose

This allow independant version tracking and updates.


## [3.2.0-beta-2]()

* `[UPDATED]` `[core, android, ktor]` - merge from Koin 3.1.6
Expand Down
2 changes: 0 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ A pragmatic lightweight dependency injection framework for Kotlin developers. `K

## Latest Version

- current stable version: `koin_version = 3.2.2`

You can find the following page to help setup your project: [Koin Gradle Setup](https://insert-koin.io/docs/setup/v3.2)

## Latest News
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,14 @@ import org.koin.android.scope.AndroidScopeComponent
import org.koin.core.annotation.KoinInternalApi
import org.koin.core.component.KoinComponent
import org.koin.core.component.KoinScopeComponent
import org.koin.core.component.getScopeId
import org.koin.core.component.getScopeName
import org.koin.core.context.GlobalContext
import org.koin.core.scope.Scope


@KoinInternalApi
fun ComponentCallbacks.getKoinScope(): Scope {
return when (this) {
is AndroidScopeComponent -> requireScope()
is AndroidScopeComponent -> scope
is KoinScopeComponent -> scope
is KoinComponent -> getKoin().scopeRegistry.rootScope
else -> GlobalContext.get().scopeRegistry.rootScope
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ import org.koin.core.scope.Scope
/**
* Android Component that can handle a Koin Scope
*/
//TODO Breaking Changes to make it 'var scope: Scope?'
interface AndroidScopeComponent {
var scope: Scope?
fun requireScope() : Scope = scope ?: error("Trying to access Android Scope on '$this' but scope is not created")
// TODO Change val to other type of value
// TODO Make it nullable
val scope: Scope
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,5 @@ fun <T : ComponentCallbacks> T.getScopeOrNull(): Scope? {
return getKoin().getScopeOrNull(getScopeId())
}

@Deprecated("Internal function not used anymore")
fun <T : ComponentCallbacks> T.newScope() = lazy { createScope() }

@Deprecated("Internal function not used anymore")
fun <T : ComponentCallbacks> T.getOrCreateScope() = lazy { getScopeOrNull() ?: createScope() }
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,18 @@ import org.koin.core.scope.Scope
*/
abstract class ScopeService : Service(), AndroidScopeComponent {

override var scope: Scope? = null
override val scope: Scope by serviceScope()

override fun onCreate() {
super.onCreate()

createServiceScope()
checkNotNull(scope)
//TODO replace with createServiceScope
}

override fun onDestroy() {
super.onDestroy()

destroyServiceScope()
//TODO be sure to close scope
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,34 @@ package org.koin.android.scope

import android.app.Service
import org.koin.android.ext.android.getKoin
import org.koin.core.annotation.KoinInternalApi
import org.koin.core.component.getScopeId
import org.koin.core.component.getScopeName
import org.koin.core.scope.Scope

fun Service.createServiceScope() {
fun Service.createServiceScope(): Scope {
if (this !is AndroidScopeComponent) {
error("Service should implement AndroidScopeComponent")
}
val koin = getKoin()
val scope =
koin.getScopeOrNull(getScopeId()) ?: koin.createScope(getScopeId(), getScopeName(), this)
this.scope = scope
return scope
}

fun Service.destroyServiceScope() {
if (this !is AndroidScopeComponent) {
error("Service should implement AndroidScopeComponent")
}
this.scope?.close()
this.scope = null
}
scope.close()
}

fun Service.serviceScope() = lazy { createServiceScope() }

/**
* Create new scope
*/
@KoinInternalApi
fun Service.createScope(source: Any? = null): Scope = getKoin().createScope(getScopeId(), getScopeName(), source)
@KoinInternalApi
fun Service.getScopeOrNull(): Scope? = getKoin().getScopeOrNull(getScopeId())
Original file line number Diff line number Diff line change
Expand Up @@ -15,43 +15,42 @@
*/
package org.koin.androidx.scope

import android.app.Activity
import android.content.ComponentCallbacks
import androidx.activity.ComponentActivity
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.LifecycleOwner
import org.koin.android.ext.android.getKoin
import org.koin.android.scope.AndroidScopeComponent
import org.koin.core.annotation.KoinInternalApi
import org.koin.core.component.getScopeId
import org.koin.core.component.getScopeName
import org.koin.core.scope.Scope

/**
* Provide Koin Scope tied to ComponentActivity
*/
@Deprecated("Delegate Lazy API is deprecatede. Please use AppCompatActivity.createActivityScope()")
fun ComponentActivity.activityScope() = LifecycleScopeDelegate<Activity>(this, this.getKoin())
@Deprecated("Delegate Lazy API is deprecatede. Please use AppCompatActivity.createActivityRetainedScope()")
fun ComponentActivity.activityRetainedScope() = LifecycleViewModelScopeDelegate(this, this.getKoin())
@Deprecated("Internal API not used anymore")
internal fun ComponentActivity.createScope(source: Any? = null): Scope = getKoin().createScope(getScopeId(), getScopeName(), source)

fun ComponentActivity.activityScope() = lazy { createActivityScope() }
fun ComponentActivity.activityRetainedScope() = lazy { createActivityRetainedScope() }

@KoinInternalApi
fun ComponentActivity.createScope(source: Any? = null): Scope = getKoin().createScope(getScopeId(), getScopeName(), source)

fun ComponentActivity.getScopeOrNull(): Scope? = getKoin().getScopeOrNull(getScopeId())

/**
* Create Scope for AppCompatActivity, given it's extending AndroidScopeComponent.
* Also register it in AndroidScopeComponent.scope
*/
fun AppCompatActivity.createActivityScope() {
fun ComponentActivity.createActivityScope(): Scope {
if (this !is AndroidScopeComponent) {
error("Activity should implement AndroidScopeComponent")
}
if (this.scope != null) {
error("Activity Scope is already created")
}
val scope = getKoin().getScopeOrNull(getScopeId()) ?: createScopeForCurrentLifecycle(this)
this.scope = scope
// if (this.scope != null) {
// error("Activity Scope is already created")
// }
return getKoin().getScopeOrNull(getScopeId()) ?: createScopeForCurrentLifecycle(this)
}

internal fun ComponentCallbacks.createScopeForCurrentLifecycle(owner: LifecycleOwner): Scope {
Expand All @@ -77,17 +76,17 @@ internal fun LifecycleOwner.registerScopeForLifecycle(
* Create Retained Scope for AppCompatActivity, given it's extending AndroidScopeComponent.
* Also register it in AndroidScopeComponent.scope
*/
fun ComponentActivity.createActivityRetainedScope() {
fun ComponentActivity.createActivityRetainedScope(): Scope {
if (this !is AndroidScopeComponent) {
error("Activity should implement AndroidScopeComponent")
}
if (this.scope != null) {
error("Activity Scope is already created")
}
// if (this.scope != null) {
// error("Activity Scope is already created")
// }
val scopeViewModel = viewModels<ScopeHandlerViewModel>().value
if (scopeViewModel.scope == null) {
val scope = getKoin().createScope(getScopeId(), getScopeName())
scopeViewModel.scope = scope
}
this.scope = scopeViewModel.scope
return scopeViewModel.scope!!
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ package org.koin.androidx.scope
import androidx.fragment.app.Fragment
import org.koin.android.ext.android.getKoin
import org.koin.android.scope.AndroidScopeComponent
import org.koin.core.Koin
import org.koin.core.component.getScopeId
import org.koin.core.component.getScopeName
import org.koin.core.scope.Scope
Expand All @@ -28,33 +27,27 @@ import org.koin.core.scope.Scope
* Link parent Activity's Scope
* Also register it in AndroidScopeComponent.scope
*/
fun Fragment.createFragmentScope() {
if (this !is AndroidScopeComponent){
fun Fragment.createFragmentScope(): Scope {
if (this !is AndroidScopeComponent) {
error("Fragment should implement AndroidScopeComponent")
}
if (this.scope != null) {
error("Fragment Scope is already created")
}
// if (this.scope != null) {
// error("Fragment Scope is already created")
// }
val scope = getKoin().getScopeOrNull(getScopeId()) ?: createScopeForCurrentLifecycle(this)
val activityScope = requireActivity().getScopeOrNull()
if (activityScope != null){
if (activityScope != null) {
scope.linkTo(activityScope)
} else {
scope.logger.debug("Fragment '$this' can't be linked to parent activity scope")
}
this.scope = scope
return scope
}

/**
* Provide scope tied to Fragment
*/
@Deprecated("Delegate Lazy API is deprecatede. Please use Fragment.createFragmentScope()")
fun Fragment.fragmentScope() = LifecycleScopeDelegate<Fragment>(this,this.getKoin()){ koin: Koin ->
val scope = koin.createScope(getScopeId(), getScopeName())
val activityScope = activity?.getScopeOrNull()
activityScope?.let { scope.linkTo(it) }
scope
}
fun Fragment.fragmentScope() = lazy { createFragmentScope() }

@Deprecated("Unused Internal API")
internal fun Fragment.createScope(source: Any? = null): Scope = getKoin().createScope(getScopeId(), getScopeName(), source)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import org.koin.core.scope.Scope
import kotlin.properties.ReadOnlyProperty
import kotlin.reflect.KProperty

@Deprecated("Use ComponentActivity.createActivityScope() or Fragment.createFragmentScope() with AndroidScopeComponent. Check Also ScopeActivity or ScopeFragment")
//TODO Deprecate
class LifecycleScopeDelegate<T>(
private val lifecycleOwner: LifecycleOwner,
private val koin: Koin,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import org.koin.core.scope.Scope
import kotlin.properties.ReadOnlyProperty
import kotlin.reflect.KProperty

@Deprecated("Use ComponentActivity.createActivityRetainedScope() with ScopeActivity or AndroidScopeComponent")
//TODO Deprecate
class LifecycleViewModelScopeDelegate(
private val lifecycleOwner: ComponentActivity,
private val koin : Koin,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@ abstract class RetainedScopeActivity(
@LayoutRes contentLayoutId: Int = 0,
) : AppCompatActivity(contentLayoutId), AndroidScopeComponent {

override var scope: Scope? = null
override val scope: Scope by activityRetainedScope()

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

createActivityRetainedScope()
checkNotNull(scope)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,11 @@ abstract class ScopeActivity(
@LayoutRes contentLayoutId: Int = 0,
) : AppCompatActivity(contentLayoutId), AndroidScopeComponent {


override var scope: Scope? = null
override val scope: Scope by activityScope()

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

createActivityScope()
checkNotNull(scope)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,7 @@ import android.os.Bundle
import android.view.View
import androidx.annotation.LayoutRes
import androidx.fragment.app.Fragment
import org.koin.android.ext.android.getKoin
import org.koin.android.scope.AndroidScopeComponent
import org.koin.core.component.KoinScopeComponent
import org.koin.core.component.getScopeId
import org.koin.core.component.getScopeName
import org.koin.core.scope.Scope

/**
Expand All @@ -36,13 +32,13 @@ import org.koin.core.scope.Scope
*/
abstract class ScopeFragment(
@LayoutRes contentLayoutId: Int = 0,
) : Fragment(contentLayoutId) , AndroidScopeComponent {
) : Fragment(contentLayoutId), AndroidScopeComponent {

override var scope: Scope? = null
override val scope: Scope by fragmentScope()

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

createFragmentScope()
checkNotNull(scope)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import org.koin.androidx.viewmodel.factory.DefaultViewModelFactory
import org.koin.core.annotation.KoinInternalApi
import org.koin.core.scope.Scope

//TODO Use instance resolution & key
//TODO Deprecate for ViewModel API 2.5 + initializers
internal fun <T : ViewModel> ViewModelProvider.resolveInstance(viewModelParameters: ViewModelParameter<T>): T {
val javaClass = viewModelParameters.clazz.java
return if (viewModelParameters.qualifier != null) {
Expand Down

0 comments on commit 3290c04

Please sign in to comment.