簡體   English   中英

Koin Dependency Injection 在本地和遠程數據源之間切換

[英]Koin Dependency Injection switching between local and remote data source

所以我正在用遠程數據源編寫這個應用程序。 我想添加本地數據庫存儲功能。 我已經設置了一個架構,我有一個接口DataSource RemoteDataSourceLocalDataSource類實現該接口。 RemoteDataSource注入了ApiInterface retrofit, LocalDataSource注入了 DAO。

現在有這個存儲庫接口和實現SomeDataRepositorySomeDataRepositoryImpl 如果我希望存儲庫能夠從 api 獲取數據並將其保存到數據庫中,我 go 應該怎么做呢?

目前,我已將RemoteDataSourceLocalDataSource類都注入到SomeDataRepositoryImpl中,以訪問來自不同數據源的方法。 這樣我就可以調用localDataSource.saveToDb()和/或remoteDatSource.fetchSomeData() int SomeRepositoryImpl class 之類的東西。但我不知道將具體實現傳遞給 class 是否是通往 go 的途徑。

但是,如果我將單個DataSource接口傳遞給SomeDataRepository ,我將必須在接口DataSource中定義一個saveToDb() function int,然后我還必須在RemoteDataSource中實現它,這不是很好。

誰能指導我解決此解決方案的最佳方法。

而且當我在做的時候,在 retrofit 的 api 接口中使用LiveData包裝器 class 包裝數據有什么好處嗎? 因為我不認為當在存儲庫上調用方法時,我想在存儲庫中觀察它,然后訪問數據以將其放入本地數據庫。

由於您希望本地數據源充當遠程數據源的回退,您可以創建另一個數據源實現,它是本地和遠程數據源的組合 此復合數據源可以包含回退邏輯並根據需要處理對遠程和本地數據源的委托 完成這些后,創建一個 Koin 模塊來構建這些,並將復合數據源綁定到數據源接口是一件簡單的事情。

假設這是您的界面和您已有的兩個數據源:

interface DataSource {
    fun getData(): Data
}

class RemoteDataSource : DataSource {
    // ...
}

class LocalDataSource : DataSource {
    // ...
}

然后你可以像這樣創建第三個實現:

class CompositeDataSource(
    val remote: RemoteDataSource, 
    val local: LocalDataSource
) : DataSource {
    override fun getData() : Data {
        return try {
            remote.getData()
        } catch (e: Exception) {
            local.getData()
        }
    }
}

要定義所有這些,您的 koin 模塊看起來像這樣

module {
    single { RemoteDataSource() }
    single { LocalDataSource() }
    single<DataSource> { CompositeDataSource(remote = get(), local = get()) }
}

編輯:如果你真正想要的是一個緩存,你可以像這樣使用本地數據源作為你的緩存:

class CompositeDataSource(
    val remote: RemoteDataSource, 
    val local: LocalDataSource
) : DataSource {
    override fun getData() : Data {
        return try {
            remote.getData().also { local.saveData(it) }
        } catch (e: Exception) {
            local.getData()
        }
    }
}

您可以嘗試下一個方法,它需要最少的更改並且對我有用:

為遠程和本地數據源添加接口,應該繼承主DataSource接口

interface QuotesDataSource {

fun getQuotes(skip: Int = 0, force: Boolean = false): Flow<List<Quote>>

suspend fun updateQuotes(quotes: List<Quote>)
}

interface QuotesRemoteDataSource : QuotesDataSource

interface QuotesLocalDataSource : QuotesDataSource

然后使用這些接口創建 koin 模塊

val repoModule = module {
  single { QuotesApi() }
  single<QuotesLocalDataSource> { QuotesDatabase(get()) }
  single<QuotesRemoteDataSource> { QuotesRemote(get()) }
  single<QuotesDataSource> {
      QuotesRepository(
          local = get<QuotesLocalDataSource>(),
          remote = get<QuotesRemoteDataSource>()
      )
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM