使用 Koin 进行数据存储的依赖注入

问题描述 投票:0回答:1

我有一个实现数据存储的 Compose 多平台项目。我使用多平台数据存储作为参考。我在注入数据存储时遇到问题。

常见主要:

fun getDataStore(producePath: () -> String): DataStore<Preferences> =
    synchronized(lock) {
        if (::dataStore.isInitialized) {
            dataStore
        } else {
            PreferenceDataStoreFactory.createWithPath(produceFile = { producePath().toPath() })
                .also { dataStore = it }
        }
    }

internal const val dataStoreFileName = "app.preferences_pb"

android主要:

fun getDataStore(context: Context): DataStore<Preferences> = getDataStore(
    producePath = { context.filesDir.resolve(dataStoreFileName).absolutePath }
)

iOS 主要 :

@OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
fun createDataStore(): DataStore<Preferences> = getDataStore(
    producePath = {
        val documentDirectory: NSURL? = NSFileManager.defaultManager.URLForDirectory(
            directory = NSDocumentDirectory,
            inDomain = NSUserDomainMask,
            appropriateForURL = null,
            create = false,
            error = null,
        )
        requireNotNull(documentDirectory).path + "/$dataStoreFileName"
    }
)

我有一个访问数据存储的类

class GameskiiSettingRepository(
    private val dataStore: DataStore<Preferences>
) 

我不知道如何注入该数据存储,并且不断收到此错误

Caused by: org.koin.core.error.NoBeanDefFoundException: No definition 
found for type 'androidx.datastore.core.DataStore'. Check your Modules
configuration and add missing type and/or qualifier!
android dependency-injection datastore koin compose-multiplatform
1个回答
0
投票

我通过声明一个实例化数据存储的

expect actual
koin 模块解决了这个问题。您的
getDataStore
签名有点不同,但这也应该适合您。

preferenceModule
中声明
commonMain

// commonMain
expect val preferenceModule: Module

actual
preferenceModule
中定义
androidMain
iosMain
实现:

// androidMain
actual val preferenceModule: Module = module {
    single { createDataStore(androidContext()) }
}

// iosMain
actual val preferenceModule: Module = module {
// Here you don't need to pass null
    single { createDataStore(null) }
}

将此模块添加到

Android
iOS
的 Koin 初始值设定项中:

// androidMain
actual class KoinInitializer(
    private val context: Context,
) {
    actual fun init() {
        startKoin {
            androidContext(context)
            androidLogger()
            modules(
                appModule, viewModelModule, preferenceModule
            )
        }
    }
}

// iosMain
actual class KoinInitializer {
    actual fun init() {
        startKoin {
            modules(appModule, viewModelModule, preferenceModule)
        }
    }
}

最后,提供

GameskiiSettingRepository
依赖项,如下所示:

single { GameskiiSettingRepository(get()) }

现在您可以将此 Repo 注入到 Viewmodel 中。

© www.soinside.com 2019 - 2024. All rights reserved.