Simon Buechner
01/05/2024, 9:18 AMp-schneider
01/05/2024, 9:34 AMSimon Buechner
01/05/2024, 9:39 AMp-schneider
01/05/2024, 9:45 AMSimon Buechner
01/05/2024, 9:47 AMp-schneider
01/05/2024, 9:49 AMoverride fun onCreate() {
super.onCreate()
startKoin {
// Log Koin into Android logger
androidLogger()
// Reference Android context
androidContext(this@MainApplication)
// Load modules
modules(appModules(databaseModule))
}
}
This is what my onCreate looks like.
I Implemented it in the androidApp module. The databaseModule is a val within androidApp because the implementation of that uses android specific dependencies and provides a custom DatabaseService interface so the other modules in the shared module can consume this DatabaseService.
On the iOS side I have a helper file/fun in shared/src/iosMain like this:
fun initKoin(databaseService: DatabaseService) {
val databaseModule =
module {
single { databaseService }
}
startKoin {
modules(appModules(databaseModule))
}
}
That is used in iosApp/iosApp/IOSApp.swift like this:
DIHelperKt.doInitKoin(databaseService: DatabaseIOS(...))
In theory I could have moved the code from onCreate() into the shared module (androidMain sourceSet).
If your library facade has a init function you can use from ios and android that should to the trick.Jacob Ras
01/05/2024, 9:53 AMSimon Buechner
01/05/2024, 9:54 AMJacob Ras
01/05/2024, 9:58 AMp-schneider
01/05/2024, 10:02 AMfun appModules(databaseModule: Module): List<Module> {
@OptIn(KoinInternalApi::class)
val databaseServiceCount =
databaseModule.mappings.values.count {
it.beanDefinition.primaryType == DatabaseService::class
}
@OptIn(KoinInternalApi::class)
<http://logger.info|logger.info> { "Logging Test ${databaseModule.mappings.keys.joinToString()}" }
require(databaseServiceCount == 1) {
"Module $databaseModule should provide 1 DatabaseService, found $databaseServiceCount"
}
return listOf(
platformModule,
databaseModule,
stateMachineModule,
)
}
so basically just a list of modules, with some extra checks to make sure the "database module" is actually providing a database.
So you should be able to use koin only in shared, just make sure koin is correctly initialized when needed.
@Jacob Ras thanks for your link, i bookmarked it for laterJeff Lockhart
01/05/2024, 7:49 PMinit
block in a class' companion object
. If there are one or more classes that are the primary entry points into using your shared module, you could call the Koin initialization function from each of them, with a check that it's only executed once.
You might consider using an isolated context as well, so your module dependencies don't leak into other modules that might also be using Koin for dependency injection.