繁体   English   中英

使用 Dagger 2 在存储库中注入应用程序上下文

[英]Inject Application Context in Repository with Dagger 2

我使用 Dagger 2.17 获取存储库中的应用程序上下文以访问资源:

上下文注入.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
}

初始化.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
    }
}

存储库.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 在存储库中获取上下文?

注意:我对 static 调用感到困惑:

context = Initialization.contextComponent.inject()

不确定这是否是好习惯。

感谢您的任何回答/评论!

您可以使用将这些资产提供给存储库的依赖项。 这个依赖可以包含对上下文的引用。 因此,您的存储库可以简单地查询此依赖项以获取所需的资产。

这是它的要点:

资产提供者:

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 特定内容的依赖最小的存储库。 因此,存储库逻辑与其运行的平台无关。 这也有助于单元测试,您不必注入上下文来测试您的存储库。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM