Android Фрагмент Dagger может получить доступ к зависимостям AppModule и ActivityModule, но не может получить доступ к зависимостям FragmentModule. - PullRequest
0 голосов
/ 10 февраля 2020

У меня есть приложение, использующее Dagger 2, в котором есть AppScope, в котором есть ActivityScope, который в свою очередь содержит FragmentScope. поля Fragment @Inject могут быть введены с помощью методов @Provides из AppModule и ActivityModule, но не с помощью методов @Provides внутри FragmentModule.

Я обязательно включил FragmentModule в подкомпонент Fragment. Также нет необходимости следить за тем, чтобы фрагмент был правильно задан для действия и приложения, поскольку он уже успешно получает зависимости от своих модулей.

Вот FragmentModule:

@Module
class SecondFragmentModule {

    @Module
    companion object {
        @JvmStatic
        @Provides
        fun provideString() : String {
            return "string"
        }
    }
}

Вот FragmentBuildersModule

@Module
abstract class FragmentsBuilderModule {

    @ContributesAndroidInjector
    abstract fun contributeFirstFragmentFragment() : FirstFragment

    @ContributesAndroidInjector(modules = [SecondFragmentModule::class])
    abstract fun contributeSecondFragment() : SecondFragment

    @ContributesAndroidInjector
    abstract fun contributeSettingsFragment() : SettingsFragment
}

Вот ActivityBuilderModule, который содержит FragmentsBuildersModule, как вы можете c:

@Module
abstract class ActivityBuildersModule {

    @ContributesAndroidInjector(modules = [
        ActivityViewModelModule::class,
        ActivityModule::class,
        FragmentsBuilderModule::class,
        FragmentsViewModelsModule::class
    ])
    abstract fun contributeHomeActivity() : HomeActivity
}

ПРИМЕЧАНИЕ. В написании вообще нет ошибок в реальном проекте мне пришлось поменять некоторые имена, чтобы сделать вопрос общим и чтобы разработчикам было проще помочь, это может привести к ошибкам в написании, но это не так в самом проекте.

РЕДАКТИРОВАТЬ:

Извините, я проверял поля @Inject во фрагменте, который они вводят, обычно моя проблема в том, что конструктор @Inject репозитория нужен FragmentViewModel, поля этого репозитория не могут быть введены из зависимостей FragmentModule, но может вводиться только из deps of ActivityModule и AppModule.

Класс ViewModel: хранилище внедряется без проблем, потому что хранилище имеет конструктор @Inject

class FragmentViewModel @Inject constructor(var repository: 
    FragmentRepository) : ViewModel() {

    lateinit var mediatorLiveData:MediatorLiveData<MutableList<POJO>>

    fun getDataFromApi() {
        mediatorLiveData = repository.getDataFromApi()
    } 
}

Класс хранилища:

class FragmentRepository @Inject constructor(var database: 
FirebaseFirestore, var collectionName: String) {

    private val mediatorLiveData:MediatorLiveData<MutableList<POJO>> = MediatorLiveData()

    fun getDataFromApi() : MediatorLiveData<MutableList<POJO>> {
        val dataListLD: MutableList<POJO> = ArrayList()
        database
            .collection(collectionName)
            .get()
            .addOnSuccessListener { result ->
                for (document in result) {
                    val dataObj = document.toObject(POJO::class.java)
                    dataListLD.add(dataObj)
                }
                mediatorLiveData.value = dataListLD
            }
        return mediatorLiveData
    }
}

Когда я пытаюсь @Provide зависимостей, необходимых для хранилища в FragmentModule, я получаю эту ошибку:

error: method create in class MasjidsRepository_Factory cannot be 
applied to given types;
required: 
Provider<FirebaseFirestore>,Provider<String>,Provider<Masjid>
found:AppModule_ProvideFirestoreDatabaseFactory,HomeModule_ProvideMasjidFactory
reason: actual and formal argument lists differ in length

1 Ответ

0 голосов
/ 10 февраля 2020

Я обнаружил проблему, репозиторий является хранилищем для viewModel, который по ошибке был помещен в HomeScope, поэтому я мог использовать deps из ActivityModule и любой области действия выше (AppScope).

Ошибка в том, что я поместил ViewModelModule для фрагментов внутри подкомпонента действия, просто переместил каждый фрагмент ViewModelModule в свой подкомпонент, и он заработал.

...