多模块项目:如何设置Dagger以提供接口,但隐藏特定于实现的依赖关系?

时间:2019-05-11 11:28:41

标签: android dagger-2 dagger modularization android-module

在我的应用程序中,我有两个模块:apprepository
repository取决于Room,并具有一个GoalRepository界面:

interface GoalRepository

和内部的GoalRepositoryImpl类,因为我不想将其或Room依赖项公开给其他模块

@Singleton
internal class GoalRepositoryImpl @Inject constructor(private val dao: GoalDao) : GoalRepository

app依赖repository来获得GoalRepository实例。
我现在有一个GoalRepositoryModule

@Module
class GoalRepositoryModule {
    @Provides
    @Singleton
    fun provideRepository(impl: GoalRepositoryImpl): GoalRepository = impl

    @Provides
    @Singleton
    internal fun provideGoalDao(appDatabase: AppDatabase): GoalDao = appDatabase.goalDao()

    @Provides
    @Singleton
    internal fun provideDatabase(context: Context): AppDatabase =
        Room.databaseBuilder(context, AppDatabase::class.java, "inprogress-db").build()
}

问题在于,(显然)由于公共provideRepository函数公开GoalRepositoryImpl(即internal类)而无法编译。
如何构造我的Dagger设置以实现我想要的?


编辑:
我尝试按照@David Medenjak的注释将provideRepository内部化,现在Kotlin编译器抱怨说它无法解决RoomDatabase依赖性:

Supertypes of the following classes cannot be resolved. Please make sure you have the required dependencies in the classpath:
    class xxx.repository.database.AppDatabase, unresolved supertypes: androidx.room.RoomDatabase    

为完整起见,请参见app模块中我组件的代码:

@Component(modules = [ContextModule::class, GoalRepositoryModule::class])
@Singleton
interface SingletonComponent

1 个答案:

答案 0 :(得分:0)

查看了Dagger生成的代码后,我了解到错误是使@Component模块内部的app依赖于@Module模块内部的repository
因此,我在@Component模块中创建了一个单独的repository,并使app模块的模块依赖于此。

代码

repository模块的组件:

@Component(modules = [GoalRepositoryModule::class])
interface RepositoryComponent {
    fun goalRepository(): GoalRepository
}

app的一个:

@Component(modules = [ContextModule::class], dependencies = [RepositoryComponent::class])
@Singleton
interface SingletonComponent

通过这种方式,RepositoryComponent负责构建Repository并了解其所有依赖性,而SingletonComponent只需要了解RepositoryComponent