Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Android 3.2.3 #1455

Merged
merged 7 commits into from
Oct 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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