Почему не всегда используются обычные компоненты Dagger
Что проверяют
Знаете ли вы, что @Component не единственная точка сборки графа, и зачем в приложении несколько уровней. Дальше спрашивают про разницу между сабкомпонентом и зависимостью компонента и зачем появился Hilt.
Как отвечать
Обычный @Component описывает один граф с одним временем жизни. Приложению этого мало, отсюда остальные механизмы:
- скоупы короче приложения: экран, фича, сессия пользователя. Держать всё в
@Singletonзначит не отпускать память после закрытия экрана, отсюда@Subcomponentсо скоупами вроде@ActivityScope; @Subcomponentпротивdependencies: сабкомпонент видит весь граф родителя и генерируется внутри него. Зависимость компонента (@Component(dependencies = ...)) требует явных методов выдачи в интерфейсе родителя, зато позволяет держать графы в разных Gradle-модулях;- аргументы времени выполнения: идентификатор заказа из интента фабрикой не собрать: нужен
@BindsInstanceв@Component.Factory, а чаще@AssistedInjectс@AssistedFactory, чтобы не заводить компонент под каждый экран; - точки входа Android: Activity и Fragment создаёт система, до конструктора не дотянуться, нужен
component.inject(this)и способ достать компонент. Ради ухода от шаблона сделан Hilt: он генерирует компоненты под жизненные циклы (SingletonComponent,ActivityRetainedComponent), даёт@AndroidEntryPointи@HiltViewModelи подменяет граф в тестах через@UninstallModulesи@BindValue; - цена сборки: граф и проверяется, и генерируется на компиляции, на большом проекте это заметное время. Отсюда переход с kapt на KSP и разделение графа по модулям.
Где спотыкаются
Складывают все зависимости в один компонент приложения. Работает до первой утечки: привязанный к экрану объект живёт весь процесс и держит контекст.
Называют @Subcomponent и @Component(dependencies) взаимозаменяемыми. Разница в видимости родительского графа и в границах пересборки, обычно её и спрашивают.
Говорят «Hilt это тот же Dagger, только проще». Hilt даёт фиксированный набор компонентов и скоупов: шаблон снимает, но и ограничивает, а нестандартный жизненный цикл всё равно описывается через @DefineComponent.