diff --git a/examples/build.gradle b/examples/build.gradle index 8367347de..2c1a56da3 100644 --- a/examples/build.gradle +++ b/examples/build.gradle @@ -22,6 +22,11 @@ buildscript { } } +plugins { + // Apply the new Kotlin Compose plugin + id 'org.jetbrains.kotlin.plugin.compose' version "$kotlin_version" apply false +} + wrapper { distributionType = Wrapper.DistributionType.ALL } diff --git a/examples/sample-android-compose/build.gradle b/examples/sample-android-compose/build.gradle index d16e3b486..4d412d198 100644 --- a/examples/sample-android-compose/build.gradle +++ b/examples/sample-android-compose/build.gradle @@ -1,12 +1,13 @@ apply plugin: 'com.android.application' apply plugin: 'kotlin-android' +apply plugin: 'org.jetbrains.kotlin.plugin.compose' apply from: "../gradle/versions.gradle" android { namespace = "org.koin.sample.androidx.compose" compileSdk android_target_version - buildToolsVersion '30.0.3' +// buildToolsVersion '30.0.3' defaultConfig { applicationId "org.koin.sample.androidx.compose" @@ -45,17 +46,16 @@ dependencies { implementation "io.insert-koin:koin-androidx-compose-navigation:$koin_version" // Compose - implementation "androidx.compose.runtime:runtime:1.5.4" - implementation "androidx.compose.ui:ui:1.5.4" - implementation "androidx.compose.foundation:foundation-layout:1.5.4" - implementation "androidx.compose.material:material:1.5.4" - - implementation "androidx.navigation:navigation-compose:2.7.6" + implementation "androidx.compose.runtime:runtime:1.7.1" + implementation "androidx.compose.ui:ui:1.7.1" + implementation "androidx.compose.foundation:foundation-layout:1.7.1" + implementation "androidx.compose.material:material:1.7.1" + implementation "androidx.navigation:navigation-compose:2.8.0" // Tooling preview - debugImplementation "androidx.compose.ui:ui-tooling:1.5.4" - implementation "androidx.compose.ui:ui-tooling-preview:1.5.4" - implementation 'androidx.appcompat:appcompat:1.6.1' + debugImplementation "androidx.compose.ui:ui-tooling:1.7.1" + implementation "androidx.compose.ui:ui-tooling-preview:1.7.1" + implementation 'androidx.appcompat:appcompat:1.7.0' testImplementation 'junit:junit:4.13.2' } \ No newline at end of file diff --git a/examples/sample-android-compose/src/main/java/org/koin/sample/androidx/compose/App.kt b/examples/sample-android-compose/src/main/java/org/koin/sample/androidx/compose/App.kt index 0a9355b29..e6f23085e 100644 --- a/examples/sample-android-compose/src/main/java/org/koin/sample/androidx/compose/App.kt +++ b/examples/sample-android-compose/src/main/java/org/koin/sample/androidx/compose/App.kt @@ -12,14 +12,11 @@ import org.koin.androidx.compose.koinViewModel import org.koin.androidx.compose.scope.KoinActivityScope import org.koin.compose.koinInject import org.koin.compose.module.rememberKoinModules -import org.koin.compose.rememberKoinInject import org.koin.core.parameter.parametersOf import org.koin.sample.androidx.compose.data.MyFactory import org.koin.sample.androidx.compose.data.MyInnerFactory import org.koin.sample.androidx.compose.data.MyScoped import org.koin.sample.androidx.compose.data.MySingle -import org.koin.sample.androidx.compose.data.sdk.SDKData -import org.koin.sample.androidx.compose.di.IsolatedContextSDK import org.koin.sample.androidx.compose.di.secondModule import org.koin.sample.androidx.compose.viewmodel.SSHViewModel import org.koin.sample.androidx.compose.viewmodel.UserViewModel diff --git a/examples/sample-android-compose/src/main/java/org/koin/sample/androidx/compose/MainActivity.kt b/examples/sample-android-compose/src/main/java/org/koin/sample/androidx/compose/MainActivity.kt index dea28e0de..1e4cabe19 100644 --- a/examples/sample-android-compose/src/main/java/org/koin/sample/androidx/compose/MainActivity.kt +++ b/examples/sample-android-compose/src/main/java/org/koin/sample/androidx/compose/MainActivity.kt @@ -21,7 +21,9 @@ class MainActivity : ScopeActivity() { setContent { KoinAndroidContext { MaterialTheme { - App() + KoinContext { + App() + } } } } diff --git a/examples/sample-android-compose/src/main/java/org/koin/sample/androidx/compose/SDKComposable.kt b/examples/sample-android-compose/src/main/java/org/koin/sample/androidx/compose/SDKComposable.kt index 4ba2e38bd..17a6ba3ac 100644 --- a/examples/sample-android-compose/src/main/java/org/koin/sample/androidx/compose/SDKComposable.kt +++ b/examples/sample-android-compose/src/main/java/org/koin/sample/androidx/compose/SDKComposable.kt @@ -7,7 +7,6 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import org.koin.compose.KoinIsolatedContext import org.koin.compose.koinInject -import org.koin.compose.rememberKoinInject import org.koin.sample.androidx.compose.data.sdk.SDKData import org.koin.sample.androidx.compose.di.IsolatedContextSDK diff --git a/examples/settings.gradle b/examples/settings.gradle index 9ee2b2bab..3276b110a 100644 --- a/examples/settings.gradle +++ b/examples/settings.gradle @@ -6,6 +6,7 @@ include 'jvm-perfs' include 'android-perfs' // ktor include 'hello-ktor' -//// Compose -//include 'sample-android-compose' + +// Compose +include 'sample-android-compose' //include 'sample-desktop-compose' \ No newline at end of file diff --git a/projects/compose/koin-compose/src/commonMain/kotlin/org/koin/compose/KoinApplication.kt b/projects/compose/koin-compose/src/commonMain/kotlin/org/koin/compose/KoinApplication.kt index 22bcf38e2..5f337e7a7 100644 --- a/projects/compose/koin-compose/src/commonMain/kotlin/org/koin/compose/KoinApplication.kt +++ b/projects/compose/koin-compose/src/commonMain/kotlin/org/koin/compose/KoinApplication.kt @@ -18,10 +18,13 @@ package org.koin.compose import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider +import androidx.compose.runtime.InternalComposeApi import androidx.compose.runtime.ProvidableCompositionLocal -import androidx.compose.runtime.ReadOnlyComposable import androidx.compose.runtime.compositionLocalOf +import androidx.compose.runtime.currentComposer +import androidx.compose.runtime.remember import org.koin.compose.application.rememberKoinApplication +import org.koin.compose.error.UnknownKoinContext import org.koin.core.Koin import org.koin.core.KoinApplication import org.koin.core.annotation.KoinInternalApi @@ -34,19 +37,14 @@ import org.koin.mp.KoinPlatformTools * Current Koin Application context */ val LocalKoinApplication: ProvidableCompositionLocal = compositionLocalOf { - getDefaultKoinContext().apply { - warnNoContext() - } + throw UnknownKoinContext() } /** * Current Koin Scope */ -@OptIn(KoinInternalApi::class) val LocalKoinScope: ProvidableCompositionLocal = compositionLocalOf { - getDefaultKoinContext().apply { - warnNoContext() - }.scopeRegistry.rootScope + throw UnknownKoinContext() } private fun getDefaultKoinContext() = KoinPlatformTools.defaultContext().get() @@ -56,9 +54,19 @@ private fun getDefaultKoinContext() = KoinPlatformTools.defaultContext().get() * * @author @author jjkester */ +@OptIn(InternalComposeApi::class) @Composable -@ReadOnlyComposable -fun getKoin(): Koin = LocalKoinApplication.current +fun getKoin(): Koin = currentComposer.run { + remember { + try { + consume(LocalKoinApplication) + } catch (_: UnknownKoinContext) { + val ctx = getDefaultKoinContext() + warningNoContext(ctx) + ctx + } + } +} /** * Retrieve the current Koin scope from the composition @@ -66,14 +74,23 @@ fun getKoin(): Koin = LocalKoinApplication.current * @author @author jjkester * */ +@OptIn(InternalComposeApi::class, KoinInternalApi::class) @Composable -@ReadOnlyComposable -fun currentKoinScope(): Scope = LocalKoinScope.current +fun currentKoinScope(): Scope = currentComposer.run { + remember { + try { + consume(LocalKoinScope) + } catch (_: UnknownKoinContext) { + val ctx = getDefaultKoinContext() + warningNoContext(ctx) + getDefaultKoinContext().scopeRegistry.rootScope + } + } +} @OptIn(KoinInternalApi::class) -private fun Koin.warnNoContext() { - logger.info("[Warning] - No Koin context defined in Compose, fallback to default Koin context." + - "Use KoinContext(), KoinAndroidContext() or KoinApplication() to setup or create Koin context with Compose and avoid such message.") +private fun warningNoContext(ctx: Koin) { + ctx.logger.error("[Warning] - No Compose Koin context setup, taking default. Use KoinContext(), KoinAndroidContext() or KoinApplication() function to setup or create Koin context and avoid such message.") } /** diff --git a/projects/compose/koin-compose/src/commonMain/kotlin/org/koin/compose/error/UnknownKoinContext.kt b/projects/compose/koin-compose/src/commonMain/kotlin/org/koin/compose/error/UnknownKoinContext.kt new file mode 100644 index 000000000..c108e5045 --- /dev/null +++ b/projects/compose/koin-compose/src/commonMain/kotlin/org/koin/compose/error/UnknownKoinContext.kt @@ -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.compose.error + +/** + * Koin Context is not found + */ +class UnknownKoinContext : Exception() \ No newline at end of file