В последнее время я много времени потратила на даггер и внедрение его в многомодульное приложение. Обычно, в моих приложениях такая архитектура, что есть модуль app, есть модули с фичами и есть модуль di. И про модуль app другие модули вообще ничего не знают. app знает только про di. И когда я использовала Koin, то с этим вообще не было никаких проблем. Коин очень прост. К сожалению, в больших приложениях он всё-таки проигрывает даггеру по скорости. Ну и меня привлекает, что в даггере всё-таки ошибки вылетают на этапе компиляции.
Ориентировалась я на статью: https://developer.android.com/training/dependency-injection/dagger-multi-module?hl=ru
И советую пройти небольшой курс по Даггеру, если вы с ним ещё не знакомы: https://codelabs.developers.google.com/codelabs/android-dagger/index.html#0
К сожалению, я не смогла придумать способ, чтобы модуль app был не зависим от других модулей и вынести всю логику в модуль di. Итоги моих исследований — есть всего два варианта: модуль app знает про все модули или все модули знают про модуль app. Второй вариант очень сомнительный, так что я остановилась на первом. Его как раз рекомендует Google. Суть метода в том, что у нас в каждом модуле будет сабкомпонент, модуль и провайдер. Хотя и этот вариант кажется костыльным. Если вы знаете лучше — напишите, пожалуйста.
- Первое, что делаем, добавляем зависимости:
implementation "com.google.dagger:dagger:2.27"
kapt "com.google.dagger:dagger-compiler:2.27"
- Дальше создаём модули. Не буду расписывать как это делать. Подразумевается, что вы это уже умеете делать. Здесь https://zen.yandex.ru/media/android_junior/sozdaem-moduli-dlia-moego-prilojeniia-api--impl-5e80906fe42ae31777317685 есть небольшое описание про создание модулей. Не забудьте добавить зависимости в модули impl и указать apply plugin: 'kotlin-kapt'.
- Создаём класс FeatureModule с аннотацией module. Это абстрактный класс, в котором мы будем описывать, как именно наши классы зависят друг от друга. Мой класс выглядит так:
- Создаём компонент в этом же модуле:
- И создаём провайдер, в котором просто возвращается новый компонент:
- Обратите внимание, что этот модуль ничего не знает про appComponent и про модуль app.
- Пришло время модуля app. Он у нас должен знать про все остальные модули, так что не забудьте указать зависимости.
- Создаём AppComponent:
- Создаём AppModule. Он у нас будет знать о всех сабкомпонентах и нужных модулях.
- Почти всё готово. Создаём интерфейс SubComponents и там указываем все провайдеры:
- И теперь этот интерфейс подтягиваем в Application:
Всё готово. При желании можно вынести AppComponent и сопутствующие в модуль di, но тогда MainComponent будет отдельным компонентом, который надо создавать в MainActivity.
Пример с кодом здесь: https://github.com/Ladgertha/Dagger-Multi-Modules