Hi everyone, Is there a way to pass `Context` to K...
# multiplatform
p
Hi everyone, Is there a way to pass
Context
to Koin when using it have shared UI across platoform? I am trying to use Datastore in Shared Module , And used actual/expect to have diff platform modules to feed Koin.
Copy code
actual fun platformModules(): Module  = module {
    factory <DatastoreProvider>{ DatastoreProviderImpl(get()) }
}
And have a single UI for all platforms
Copy code
@Composable
fun App() {
    KoinApplication(allKoinModules) {
        Navigator(HomeScreen)
    }

}
Datastore needs Android Context , How can we do that?
s
p
There should be a better way then this, maybe by using actual/expect for `App`(Main UI calling point for all platform) itself , and Android one will take Context as dependency , and then use “Koin Android initializer ” rather then “Koin Compose initializer”. But maybe there is a better way.
s
You can't get hold of the Android context without referencing it somewhere after the application initializes.
p
I can create a custom Application and just access it via static way. Won’t it work?
🚫 1
s
it will, this
app-initializer
is useful for common modules/libraries because if the end user creates their own application class, the application class method won't work.
p
It did work , but idk how i feel about keeping my CustomApplication in shared module
s
Yeah exactly, also you can't do this again if you need the context in another non-dependent module.
1
j
This snippet you're sharing, it looks like that's already what you want.
Copy code
actual fun platformModules(): Module  = module {
    factory <DatastoreProvider>{ DatastoreProviderImpl(get()) }
}
It's an
actual
implementation of a platform module. Good. It provides the
DataStoreProviderImpl
and in its constructor does
get()
to get the Android Context (which is available by default in Koin on Android). Also good! Doesn't it work?
p
As far as i know Context is not available by default, we have to add androidContext during koin init, And i am not using android koin , i am using the Compose Multiplatofrm version of it , so koin init happens inside shared module itself.And in that androidContext method is not there by koin
j
Right! So there's two ways to go here. One is to instantiate Koin not in the common code, but in the platform code (so using the androidContext init in the
android
source set). You still use the modules from the common code, it's just that the starting is in a platform source set. Like in the KMP example: https://github.com/InsertKoinIO/hello-kmp/blob/main/androidApp/src/main/java/com/example/helloworldkmp/android/MainApplication.kt That's what I'm doing in my projects. Another way would be to dynamically add a module that provides the Android Context to the Koin graph/tree from your custom
Application
. Seems that possible but I haven't done that with Koin. See https://github.com/InsertKoinIO/koin/issues/419
5
💯 2
p
I do also initialize koin in each platform separately, for these same reasons. When creating a class that depends on many platform specific dependencies, the recommended expect factory function that returns an interface is not enough.
2
p
Thanks for all the suggestions I did kinda the same , still using “koin compose”, but just passing all the dependencies to the Mail caller method and adding it to the graph. Only downside is now we have one caller each Platform but quite satisfied
Copy code
@Composable
fun AndroidApp(context: Context) {
    KoinApplication(moduleList = {
        sharedModule + module {
            factory<Context> { context.applicationContext }
        }
    }) {
        Navigator(HomeScreen)
    }
}
Something like this.
👍 1