Мультимодульный проект: как настроить Dagger для предоставления интерфейса, но скрыть зависимости от реализации? - PullRequest
0 голосов
/ 11 мая 2019

В моем приложении у меня есть два модуля: app и repository.
repository зависит от комнаты и имеет интерфейс GoalRepository:

interface GoalRepository

и GoalRepositoryImpl класс, который является внутренним, как Я не хочу показывать его или зависимость Room от других модулей :

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

app зависит от repository, чтобы получитьGoalRepository instance.
У меня есть 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 для достижения того, чего я хочу?


Редактировать:
Я пытался сделать provideRepositoryвнутренняя в соответствии с комментарием @David Medenjak, и теперь компилятор 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 голосов
/ 11 мая 2019

Посмотрев на код, который генерировал 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...