Skip to content

Commit

Permalink
Compose KoinIsolatedContext to help run child composables using a iso…
Browse files Browse the repository at this point in the history
…lated Koin context
  • Loading branch information
arnaudgiuliani committed Aug 31, 2023
1 parent 49b298c commit 8ca591b
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/

@file:OptIn(KoinInternalApi::class)

package org.koin.compose
Expand All @@ -21,6 +22,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.compositionLocalOf
import org.koin.core.Koin
import org.koin.core.KoinApplication
import org.koin.core.annotation.KoinInternalApi
import org.koin.core.module.Module
import org.koin.dsl.KoinAppDeclaration
Expand Down Expand Up @@ -84,4 +86,31 @@ fun KoinApplication(
) {
content()
}
}

//TODO Test Isolated Context
/**
* Provides Koin Isolated context to be setup into LocalKoinApplication & LocalKoinScope via CompositionLocalProvider,
* to be used by child Composable.
*
* This allows to use an isolated context, directly in all current Composable API
*
* Koin isolated context has to created with koinApplication() function, storing the instance in a static field
*
* @param context - Koin isolated context
* @param content - child Composable
*
* @author Arnaud Giuliani
*/
@Composable
fun KoinIsolatedContext(
context: KoinApplication,
content: @Composable () -> Unit
) {
CompositionLocalProvider(
LocalKoinApplication provides context.koin,
LocalKoinScope provides context.koin.scopeRegistry.rootScope
) {
content()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import org.koin.androidx.compose.koinViewModel
import org.koin.androidx.compose.scope.KoinActivityScope
import org.koin.compose.KoinIsolatedContext
import org.koin.compose.koinInject
import org.koin.compose.module.rememberKoinModules
import org.koin.compose.rememberKoinInject
Expand All @@ -18,6 +19,8 @@ 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
Expand All @@ -37,6 +40,7 @@ fun App(userViewModel: UserViewModel = koinViewModel()) {
SingleComposable(parentStatus = updatedTime)
FactoryComposable(parentStatus = updatedTime)
ViewModelComposable(parentStatus = updatedTime)
IsolatedSDKComposable(parentStatus = updatedTime)
}
}

Expand Down Expand Up @@ -85,6 +89,7 @@ fun ViewModelComposable(
// }
//}


@Composable
fun SingleComposable(
parentStatus: String = "- status -",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,19 @@ package org.koin.sample.androidx.compose
import android.os.Bundle
import androidx.activity.compose.setContent
import androidx.compose.material.MaterialTheme
import org.koin.android.ext.android.getKoin
import org.koin.androidx.scope.ScopeActivity
import org.koin.sample.androidx.compose.data.sdk.SDKData
import java.util.logging.Logger

class MainActivity : ScopeActivity() {

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

// ensure SDK is not accessible in main context
assert(getKoin().getOrNull<SDKData>() == null)

setContent {
MaterialTheme { App() }
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package org.koin.sample.androidx.compose

import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import org.koin.compose.KoinIsolatedContext
import org.koin.compose.rememberKoinInject
import org.koin.sample.androidx.compose.data.sdk.SDKData
import org.koin.sample.androidx.compose.di.IsolatedContextSDK


@Composable
fun IsolatedSDKComposable(
parentStatus: String = "- status -",
) {
KoinIsolatedContext(IsolatedContextSDK.koinApp) {
SDKComposable(parentStatus)
}
}

@Composable
private fun SDKComposable(
parentStatus: String = "- status -",
sdkData: SDKData = rememberKoinInject()
) {
var created by remember { mutableStateOf(false) }

if (created) {
clickComponent("sdkData", sdkData.id, parentStatus) {
ButtonForCreate("-X- sdkData") { created = !created }
}
} else {
ButtonForCreate("(+) sdkData") { created = !created }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package org.koin.sample.androidx.compose.data.sdk

import java.util.UUID

class SDKData {
val id = UUID.randomUUID().toString()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package org.koin.sample.androidx.compose.di

import org.koin.dsl.koinApplication
import org.koin.dsl.module
import org.koin.sample.androidx.compose.data.sdk.SDKData

val sdkModule = module {
single { SDKData() }
}

object IsolatedContextSDK {

val koinApp = koinApplication {
modules(sdkModule)
}

}

0 comments on commit 8ca591b

Please sign in to comment.