使用 Dagger 2 在存储库中注入应用程序上下文
Inject Application Context in Repository with Dagger 2
我使用 Dagger 2.17 获取存储库中的应用程序上下文以访问资源:
ContextInjection.kt:
@Module
class ContextModule(private val context: Context) {
@Singleton
@Provides
fun providesContext(): Context {
return context
}
}
@Singleton
@Component(modules = [ContextModule::class])
interface ContextComponent {
fun inject(): Context
}
Initialization.kt:
class Initialization : Application() {
override fun onCreate() {
super.onCreate()
contextComponent = DaggerContextComponent.builder()
.contextModule(ContextModule(this.applicationContext))
.build()
}
companion object { // for access in repository
lateinit var contextComponent: ContextComponent
}
}
Repository.kt:
@Singleton
class Repository {
@Inject
lateinit var context: Context
/** the method is invoked from view model class */
fun loadList(pageIndex: Int): List<String> {
context = Initialization.contextComponent.inject()
val input = context.assets.open("tab1/item1/description.txt")
...
}
}
ViewModel.kt:
class PageViewModel : ViewModel() {
@NonNull
private val repository = Repository()
private val pageIndex = MutableLiveData<Int>()
val items = Transformations.map<Int, List<String>>(pageIndex) { index: Int ->
repository.loadList(index)
}
fun setIndex(index: Int) {
pageIndex.value = index
}
}
这有效,但我有下一个 问题:
有没有其他(更好的)方法可以使用 Dagger 获取存储库中的上下文?
注意:
我对静态调用感到困惑:
context = Initialization.contextComponent.inject()
不确定这是否是好的做法。
感谢您的任何 answer/comment!
您可以使用向存储库提供这些资产的依赖项。并且这种依赖关系可以包含对上下文的引用。因此您的存储库可以简单地查询此依赖项以获取所需的资产。
要点如下:
资产提供者:
class AssetProvider @Inject constructor(
private val context: Context
) {
fun getDescription() = context.assets.open("tab1/item1/description.txt")
}
存储库:
@Singleton
class Repository @Inject constructor(
private val assetProvider: AssetProvider
) {
fun loadList(pageIndex: Int): List<String> {
val input = assetProvider.getDescription()
...
}
}
我喜欢拥有对 Android 特定内容的依赖性最小的存储库。因此,存储库逻辑与其运行的平台无关。这也有助于单元测试,您不必注入上下文来测试您的存储库。
我使用 Dagger 2.17 获取存储库中的应用程序上下文以访问资源:
ContextInjection.kt:
@Module
class ContextModule(private val context: Context) {
@Singleton
@Provides
fun providesContext(): Context {
return context
}
}
@Singleton
@Component(modules = [ContextModule::class])
interface ContextComponent {
fun inject(): Context
}
Initialization.kt:
class Initialization : Application() {
override fun onCreate() {
super.onCreate()
contextComponent = DaggerContextComponent.builder()
.contextModule(ContextModule(this.applicationContext))
.build()
}
companion object { // for access in repository
lateinit var contextComponent: ContextComponent
}
}
Repository.kt:
@Singleton
class Repository {
@Inject
lateinit var context: Context
/** the method is invoked from view model class */
fun loadList(pageIndex: Int): List<String> {
context = Initialization.contextComponent.inject()
val input = context.assets.open("tab1/item1/description.txt")
...
}
}
ViewModel.kt:
class PageViewModel : ViewModel() {
@NonNull
private val repository = Repository()
private val pageIndex = MutableLiveData<Int>()
val items = Transformations.map<Int, List<String>>(pageIndex) { index: Int ->
repository.loadList(index)
}
fun setIndex(index: Int) {
pageIndex.value = index
}
}
这有效,但我有下一个 问题: 有没有其他(更好的)方法可以使用 Dagger 获取存储库中的上下文?
注意: 我对静态调用感到困惑:
context = Initialization.contextComponent.inject()
不确定这是否是好的做法。
感谢您的任何 answer/comment!
您可以使用向存储库提供这些资产的依赖项。并且这种依赖关系可以包含对上下文的引用。因此您的存储库可以简单地查询此依赖项以获取所需的资产。
要点如下:
资产提供者:
class AssetProvider @Inject constructor(
private val context: Context
) {
fun getDescription() = context.assets.open("tab1/item1/description.txt")
}
存储库:
@Singleton
class Repository @Inject constructor(
private val assetProvider: AssetProvider
) {
fun loadList(pageIndex: Int): List<String> {
val input = assetProvider.getDescription()
...
}
}
我喜欢拥有对 Android 特定内容的依赖性最小的存储库。因此,存储库逻辑与其运行的平台无关。这也有助于单元测试,您不必注入上下文来测试您的存储库。