erfan
02/03/2024, 7:21 AMimport com.example.Database
expect class DriverFactory {
fun createDriver(): SqlDriver
}
fun createDatabase(driverFactory: DriverFactory): Database {
val driver = driverFactory.createDriver()
val database = Database(driver)
// Do more work with the database (see below).
}
in androidMain:
actual class DriverFactory(private val context: Context) {
actual fun createDriver(): SqlDriver {
return AndroidSqliteDriver(Database.Schema, context, "test.db")
}
}
in jvmMain:
actual class DriverFactory {
actual fun createDriver(): SqlDriver {
val driver: SqlDriver = JdbcSqliteDriver(JdbcSqliteDriver.IN_MEMORY)
Database.Schema.create(driver)
return driver
}
}
as you can see, the constructor for these classes are different. when I implement the exact same thing stated in sqldelight documentation, I get this compile error :
Actual class 'DriverFactory' has no corresponding members for expected class members:
public constructor DriverFactory() defined in nikted.fitting.compose.kmp.platform.DriverFactory The following declaration is incompatible because number of value parameters is different:
public constructor DriverFactory(context: Context) defined in nikted.fitting.compose.kmp.platform.DriverFactory
I have tried putting aside koin ( only for this class ) and using the direct singleton instance of Android like this:
actual class DriverFactory {
val context = AndroidApp.INSTANCE.applicationContext
actual fun createDriver(): SqlDriver {
return AndroidSqliteDriver(FittingDb.Schema, context, "FittingDb.db")
}
}
but it will lead to other problems like when testing the application on android. I would really appreciate it if someone could show me a way that I can resolve this dependency from koin instead of creating a direct instance. thanksMichael Paus
02/03/2024, 9:24 AMactual class DatabaseDriverFactoryImpl actual constructor() : DatabaseDriverFactory {
private lateinit var activity: ComponentActivity
fun init(activity: ComponentActivity) {
this.activity = activity
}
override fun createDatabaseDriver(dbFilePath: String): SqlDriver {
return AndroidSqliteDriver(AIPDatabase.Schema, activity.applicationContext, dbFilePath)
}
}
As you can see I have added an init method to it. I call this when the model is initialized from the Activity like this:
val databaseDriverFactory: DatabaseDriverFactory by inject()
(databaseDriverFactory as DatabaseDriverFactoryImpl).init(activity)
Darron Schall
02/03/2024, 6:20 PMDriverFactory
as part of a platformModule
that each platform defines. You can see a concrete example of this kind of approach in https://github.com/touchlab/KaMPKit.
• Have the common Koin module leverage the platform module: https://github.com/touchlab/KaMPKit/blob/main/shared/src/commonMain/kotlin/co/touchlab/kampkit/Koin.kt#L24 - Note that the expect
is here at the end of that file: https://github.com/touchlab/KaMPKit/blob/main/shared/src/commonMain/kotlin/co/touchlab/kampkit/Koin.kt#L87
• Create the Android platformModule in androidMain: https://github.com/touchlab/KaMPKit/blob/main/shared/src/androidMain/kotlin/co/touchlab/kampkit/KoinAndroid.kt#L12
• Create the iOS platformModule in iOSMain: https://github.com/touchlab/KaMPKit/blob/main/shared/src/iosMain/kotlin/co/touchlab/kampkit/KoinIOS.kt#L30