所以我正在使用远程数据源编写这个应用程序。我想添加本地数据库存储功能。我已经建立了一个架构,其中我有一个接口(interface)DataSource
。 RemoteDataSource
和 LocalDataSource
类实现该接口(interface)。 RemoteDataSource
通过 ApiInterface
改造注入(inject),LocalDataSource
通过 DAO 注入(inject)。
现在有了这个存储库接口(interface)和实现 SomeDataRepository
和 SomeDataRepositoryImpl
。如果我希望存储库能够从 api 获取数据并将其保存到数据库中,我该怎么做?
目前,我已将 RemoteDataSource
和 LocalDataSource
类注入(inject)到 SomeDataRepositoryImpl
中,以访问来自不同数据源的方法。这样我就可以调用 localDataSource.saveToDb()
和/或 remoteDatSource.fetchSomeData()
int SomeRepositoryImpl
类。但我不知道将具体实现传递给类是否是正确的方法。
但是,如果我将单个 DataSource
接口(interface)传递给 SomeDataRepository
,我将必须定义一个 saveToDb()
函数接口(interface) DataSource
,然后我还必须在 RemoteDataSource
中实现它,这不太好。
任何人都可以指导我了解此解决方案的最佳方法是什么。
而且,当我这样做时,在 api 接口(interface)中使用 LiveData
包装器类包装数据进行改造是否有好处?因为我不认为当在存储库上调用方法时,我想在存储库中观察它,然后访问数据以将其放入本地数据库。
最佳答案
由于您希望本地数据源充当远程数据源的后备,因此您可以创建另一个数据源实现,即 composition本地和远程数据源。此复合数据源可以包含回退逻辑并处理 delegation根据需要连接到远程和本地数据源。完成此操作后,创建一个 Koin 模块来构造这些,并将复合数据源绑定(bind)到数据源接口(interface)就很简单了。
假设这是您的界面和您已有的两个数据源:
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()
}
}
}
关于android - Koin依赖注入(inject)本地和远程数据源之间的切换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61848367/