Настройка Dependency Injection (Dagger 2) в Android-приложении

Мы сталкиваемся с проектами, где Dagger 2 добавляют в середине разработки. Результат — запутанный граф, утечки памяти и баги, которые невозможно воспроизвести локально. Dagger генерирует код во время компиляции — никакой рефлексии, но за эту безопасность платим архитектурной дисциплиной. Наш опыт: н

Разработка и поддержка любых видов мобильных приложений:

Информационные и развлекательные мобильные приложения
Новостные приложения, игры, справочники, онлайн-каталоги, погодные, фитнес и здоровье, туристические, образовательные, социальные сети и мессенджеры, квиз, блоги и подкасты, форумы, агрегаторы
Мобильные приложения электронной коммерции
Интернет-магазины, B2B-приложения, маркетплейсы, онлайн-обменники, кэшбэк-сервисы, биржи, дропшиппинг-платформы, программы лояльности, доставка еды и товаров, платежные системы
Мобильные приложения для управления бизнес-процессами
CRM-системы, ERP-системы, управление проектами, инструменты для команды продаж, учет финансов, управление производством, логистика и доставка, управление персоналом, системы мониторинга данных
Мобильные приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, платформы предоставления электронных услуг, платформы кешбека, видеохостинги, тематические порталы, платформы онлайн-бронирования и записи, платформы онлайн-торговли

Это лишь некоторые из типы мобильных приложений, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента.

Услуги, которые мы предлагаем
Показано 1 из 1Все 1734 услуг
Настройка Dependency Injection (Dagger 2) в Android-приложении
Средний
~3-5 дней

Наши компетенции:

Часто задаваемые вопросы

Последние работы

  • image_mobile-applications_feedme_467_0.webp
    Разработка мобильного приложения для компании FEEDME
    895
  • image_mobile-applications_xoomer_471_0.webp
    Разработка мобильного приложения для компании XOOMER
    782
  • image_mobile-applications_rhl_428_0.webp
    Разработка мобильного приложения для компании RHL
    1216
  • image_mobile-applications_zippy_411_0.webp
    Разработка мобильного приложения для компании ZIPPY
    1079
  • image_mobile-applications_affhome_429_0.webp
    Разработка мобильного приложения для компании Affhome
    1002
  • image_mobile-applications_flavors_409_0.webp
    Разработка мобильного приложения для компании FLAVORS
    597

Мы сталкиваемся с проектами, где Dagger 2 добавляют в середине разработки. Результат — запутанный граф, утечки памяти и баги, которые невозможно воспроизвести локально. Dagger генерирует код во время компиляции — никакой рефлексии, но за эту безопасность платим архитектурной дисциплиной. Наш опыт: настройка с нуля занимает 3–5 дней, а рефакторинг хаотичного внедрения — от недели. За более чем 5 лет работы мы настроили Dagger на 30+ проектах разного масштаба — от стартапов до enterprise-приложений. Гарантируем чистый DI-код без сюрпризов в рантайме. Получите консультацию по вашему проекту: закажите анализ текущей архитектуры.

Как правильно спроектировать граф компонентов?

Стандартная схема для большого приложения: AppComponent (Singleton) → ActivityComponent (PerActivity) → FragmentComponent (PerFragment). Каждый уровень — сабкомпонент или зависимый компонент. Ошибка архитектуры — помещать все зависимости в AppComponent, что увеличивает время сборки и усложняет тестирование.

@Singleton @Component(modules = [AppModule::class, NetworkModule::class, DatabaseModule::class]) interface AppComponent { fun inject(app: App) fun activityComponentBuilder(): ActivityComponent.Builder } @Module class NetworkModule { @Provides @Singleton fun provideOkHttpClient(): OkHttpClient { return OkHttpClient.Builder() .addInterceptor(AuthInterceptor()) .connectTimeout(30, TimeUnit.SECONDS) .build() } @Provides @Singleton fun provideRetrofit(client: OkHttpClient): Retrofit { return Retrofit.Builder() .baseUrl(BuildConfig.API_URL) .client(client) .addConverterFactory(GsonConverterFactory.create()) .build() } } 

Почему скоупы — частая причина трудноуловимых багов?

Самая частая ошибка — неправильные скоупы. Если UserRepository объявлен @Singleton, а AuthToken внутри него хранится в памяти, то после logout без пересоздания компонента старый токен остаётся в живом объекте. Это приводит к запросам с чужим токеном — продакшн-баг, который воспроизводится только при конкретном сценарии. Решение: @Singleton-компоненты не должны содержать изменяемое состояние, зависящее от сессии пользователя. Сессионные зависимости выносятся в @UserScope:

@Scope @Retention(AnnotationRetention.RUNTIME) annotation class UserScope @UserScope @Subcomponent(modules = [UserModule::class]) interface UserComponent { @Subcomponent.Factory interface Factory { fun create(@BindsInstance userId: String): UserComponent } fun inject(profileFragment: ProfileFragment) } 

UserComponent создаётся после логина, уничтожается после logout. Все зависимости, привязанные к пользователю, живут ровно столько, сколько нужно. Ниже таблица типичных ошибок:

Типичная ошибка Последствие Решение
Изменяемое состояние в @Singleton Утечка данных при logout Вынос в @UserScope
@Singleton зависимость с медленной инициализацией Замедление старта приложения Использовать @Lazy или Provider
Отсутствие @BindsInstance Необходимость ручного создания компонента Добавлять @BindsInstance для динамических параметров

Дополнительно стоит упомянуть, что неправильное использование скоупов может привести к утечкам памяти из-за случайного захвата Activity контекста в @Singleton. Мы всегда проверяем граф на такие сценарии.

Multibindings и плагинная архитектура

@IntoMap с @ViewModelKey — паттерн для инжекции ViewModels через ViewModelProvider.Factory. Dagger создаёт Map<Class<out ViewModel>, Provider<ViewModel>>, фабрика выбирает нужный класс. Без этого паттерна каждую ViewModel приходится отдельно объявлять в компоненте.

@Module abstract class ViewModelModule { @Binds @IntoMap @ViewModelKey(LoginViewModel::class) abstract fun bindLoginViewModel(vm: LoginViewModel): ViewModel @Binds @IntoMap @ViewModelKey(ProfileViewModel::class) abstract fun bindProfileViewModel(vm: ProfileViewModel): ViewModel } 

Этот же подход применим для плагинной архитектуры, где каждый модуль регистрирует свои зависимости через @IntoSet или @IntoMap. Мы использовали это в проекте с 10+ фича-модулями — Dagger автоматически собирает все предоставленные реализации.

Kapt и KSP: что выбрать для сборки?

Dagger 2 традиционно работает с kapt. Начиная с версии 2.50 доступна экспериментальная поддержка KSP, которая ускоряет инкрементальные сборки. На проекте с ~200 Dagger-аннотациями переход с kapt на KSP сократил время clean build с 4.5 до 2.8 минут — экономия времени разработки значительная.

// build.gradle.kts plugins { id("com.google.devtools.ksp") } dependencies { implementation("com.google.dagger:dagger:2.51") ksp("com.google.dagger:dagger-compiler:2.51") } 
Параметр Kapt KSP (экспериментальный)
Время clean build (200 аннотаций) 4.5 мин 2.8 мин
Инкрементальная сборка Обычная Ускоренная
Поддержка Dagger Полная С 2.50, не все фичи

Также стоит помнить про обфускацию: ProGuard/R8 могут удалить классы, созданные Dagger, если не добавить правила keep. Мы включаем это в конфигурацию.

Как тестировать приложение с Dagger?

Dagger и тесты — отдельная история. Стандартный подход: тестовые модули, которые заменяют продакшн-зависимости на фейки:

@Component(modules = [TestNetworkModule::class, DatabaseModule::class]) interface TestAppComponent : AppComponent @Module class TestNetworkModule { @Provides @Singleton fun provideApiService(): ApiService = FakeApiService() } 

В Espresso-тестах DaggerTestAppComponent подставляется вместо основного в App.appComponent до запуска теста. Без этой замены интеграционные тесты уходят на реальный сервер. Мы также используем TestCoroutineDispatcher для имитации задержек.

Когда выбирать Dagger 2, а не Hilt

Hilt — обёртка над Dagger с предзаданной структурой компонентов. Если нужны нестандартные скоупы, мультимодульный граф с независимыми компонентами или Dagger уже в проекте — Dagger 2 даёт полный контроль. Hilt быстрее стартует, но ограничивает в сложных архитектурах. В наших проектах мы часто комбинируем Dagger с Hilt в разных модулях.

Что входит в настройку Dagger 2 под ключ

  • Анализ архитектуры и проектирование графа компонентов
  • Создание модулей для сети, БД, shared preferences
  • Настройка скоупов (Singleton, PerActivity, UserScope)
  • Интеграция с ViewModel через мультибиндинг
  • Конфигурация тестового компонента с фейками
  • Переход с kapt на KSP при необходимости
  • Документация по поддержке графа

Стоимость рассчитывается индивидуально. Настройка с нуля — 3–5 дней, рефакторинг — от недели. Получите консультацию: напишите нам, оценим ваш проект. Хотите внедрить Dagger 2 без головной боли? Свяжитесь с нами, мы проведём аудит вашего DI-кода.