首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何从Android动态特性模块向App模块注入/提供存储库

如何从Android动态特性模块向App模块注入/提供存储库
EN

Stack Overflow用户
提问于 2021-02-23 15:46:06
回答 1查看 815关注 0票数 2

我正在调查我当前Android应用程序中的动态功能模块。

我的应用程序由一个App、多个静态模块和一个动态特性模块组成。

我试图将动态特性模块中声明的存储库类注入我的一个静态模块中的存储库类。

我有一个公共共享模块,它包含一个接口,它定义了

我的动态功能模块有一个类似于以下内容的存储库类:-

代码语言:javascript
复制
class DynamicFeatureRepository @Inject constructor(private val applicationContext: Context) : MyExperimentable {

    override fun accessDynamicModuleRawData(): List<MyExperimentDO> {
        val myExperimentDOs = mutableListOf<MyExperimentDO>()
        applicationContext.resources.openRawResource(R.raw.data).use {
            val reader = BufferedReader(InputStreamReader(it))
            while (reader.ready()) {
                val columns = reader.readLine().split(",")
                myExperimentDOs.add(
                    MyExperimentDO(
                        myExperimentId = columns[0].toLong(),
                        selected = columns[1].toBoolean(),
                        myExperimentName = columns[2],
                        myExperiment = columns[3]
                    )
                )
            }
        }

        return myExperimentDOs
    }

    override fun generate(data: String): Map<String, String> {

        return emptyMap()
    }
}

我有另一个使用上述动态特性模块存储库的静态模块

我相信Dagger子组件将允许我将这个动态特性模块存储库注入到我的静态模块类中,但是我不知道如何实现这一点。

到目前为止,我在我的公共模块中声明了以下Dagger类:

代码语言:javascript
复制
import dagger.Module
import dagger.Subcomponent
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent

@Subcomponent
interface MyExperimentComponent {
    fun inject(myExperimentable: MyExperimentable)

    @Subcomponent.Factory
    interface Factory {
        fun create(): MyExperimentComponent
    }
}

@InstallIn(SingletonComponent::class)
@Module(subcomponents = [MyExperimentComponent::class])
class SubcomponentsModule {}

在我的动态功能模块中,我有一个匕首类:-

代码语言:javascript
复制
@InstallIn(SingletonComponent::class)
@Module
class ExperimentModule() {
    @Provides
    fun getMyExperiment(@ApplicationContext appContext: Context): MyExperimentable {
       return DynamicFeatureRepository(appContext)
    }
}

在我的静态模块中,我有一个@Inject

代码语言:javascript
复制
@Inject
lateinit var myExperimentable: MyExperimentable

我的应用程序构建并运行,但是我的静态模块中的@Inject并不满足,因为我的应用程序失败了

代码语言:javascript
复制
kotlin.UninitializedPropertyAccessException: lateinit property myExperimentable has not been initialized

我哪里出错了?

如何@为我的一个静态模块提供动态功能模块repo

以下是我的静态模块中的“注入站点”:

代码语言:javascript
复制
class MyRepository @Inject constructor(private val datastore: DataStore, private val workMonitor: WorkMonitor) {

    @Inject
    lateinit var myExperimentable: MyExperimentable

...

    fun accessDynamicModuleRawData() {
        val rawData = myExperimentable.accessDynamicModuleRawData()
        Timber.i("xxx ${rawData.size}")
    }
}

Android文档中有一个突出显示的注释:-

注意:每当您想要创建ApplicationComponent的子组件时,都会发生此问题。如果需要创建依赖于功能模块的常规分级模块,并且需要创建依赖于该功能模块中定义的组件的组件,则可以像往常一样使用子组件。

这不是我的案子吗?我的静态模块需要/依赖于在动态特性模块中定义的组件。这个评论让我相信我可以使用Dagger子组件来解决我的问题。如果这是真的,“如何”使用子组件来启用将我的DFM回购注入我的静态模块回购?

更新

我已将此@EntryPoint添加到我的应用程序模块中:-

代码语言:javascript
复制
@EntryPoint
@InstallIn(SingletonComponent::class)
interface MyExperimentableEntryPointInterface {

    fun getMyExperimentable(): MyExperimentable

}

这将允许我在我的目标库中使用这个

代码语言:javascript
复制
val bar = EntryPoints.get(appContext, MyExperimentableEntryPointInterface::class.java).getMyExperimentable()

我遇到的问题是如何从DFM中"Provide“MyExperimentable的实现。

在我的DFM中,我试过这样做:-

代码语言:javascript
复制
@Module
@DisableInstallInCheck
object DynamicFeatureRepositoryeModule {

    @Provides
    @Singleton
    fun provideDynamicFeatureRepository(): MyExperimentable {
        return DynamicFeatureRepository()
    }
}

然而,我在构建时得到了这个异常:-

代码语言:javascript
复制
error: [Dagger/MissingBinding] MyExperimentable cannot be provided without an @Provides-annotated method.

在我的应用程序中提供DFM存储库的实例时,我遗漏了什么?

更新解决方案

我设法使用Dagger实现了想要的结果,并将我的解决方案建立在这个示例上--我不喜欢这个方面--尽管这是使用反射的

EN

回答 1

Stack Overflow用户

发布于 2021-02-24 19:23:31

为什么不在MyExperimentable类中添加MyRepository依赖项作为构造函数注入。通常,我们为活动/视图/片段进行字段注入。如果我们使用构造函数注入来完成它,那么您将在编译期间得到确切的错误原因。

愿这样的事情:

代码语言:javascript
复制
class MyRepository @Inject constructor(private val datastore: DataStore, private val workMonitor: WorkMonitor, private val myExperimentable: MyExperimentable) {

    //@Inject
    //lateinit var myExperimentable: MyExperimentable

...

    fun accessDynamicModuleRawData() {
        val rawData = myExperimentable.accessDynamicModuleRawData()
        Timber.i("xxx ${rawData.size}")
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66336398

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档