← Назад к вопросам

Опиши структуру Dagger

2.0 Middle🔥 171 комментариев
#Dependency Injection#Архитектура и паттерны

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Структура Dagger как DI-фреймворка для Android

Dagger — это компиляторно-ориентированный фреймворк для инъекции зависимостей (DI) в Java/Kotlin, разработанный Google. Его архитектура основана на аннотациях и генерации кода во время компиляции, что обеспечивает высокую производительность и отсутствие ошибок времени выполнения в сравнении с рефлексивными решениями.

Ключевые компоненты Dagger 2

Аннотации для определения зависимостей

// Модуль предоставляет зависимости
@Module
class NetworkModule {
    @Provides
    fun provideHttpClient(): OkHttpClient {
        return OkHttpClient.Builder().build()
    }
    
    // Можно указать контекст, если зависимость нужна в разных экземплярах
    @Provides
    @Singleton
    fun provideApiService(client: OkHttpClient): ApiService {
        return Retrofit.Builder()
            .baseUrl("https://api.example.com/")
            .client(client)
            .build()
            .create(ApiService::class.java)
    }
}

Компоненты как точки инъекции

// Компонент связывает модули и определяет, где инжектить
@Component(modules = [NetworkModule::class, RepositoryModule::class])
@Singleton
interface ApplicationComponent {
    // Метод для инъекции в конкретный класс
    fun inject(activity: MainActivity)
    
    // Фабричный метод для получения зависимости напрямую
    fun getRepository(): DataRepository
}

Аннотации для внедрения

class MainActivity : AppCompatActivity() {
    // Поле инъекции
    @Inject
    lateinit var repository: DataRepository
    
    // Инъекция через конструктор (часто для классов без Android контекста)
    class DataRepository @Inject constructor(
        private val apiService: ApiService,
        private val database: AppDatabase
    ) {
        fun fetchData() { /* ... */ }
    }
}

Процесс работы Dagger

  1. Анализ аннотаций — Dagger анализирует @Module, @Provides, @Inject и @Component во время компиляции.
  2. Генерация кода — Создает классы:
    • DaggerApplicationComponent — реализация компонента.
    • Фабрики и поставщики для каждого @Provides метода и @Inject конструктора.
  3. Валидация графа зависимостей — Проверяет циклические зависимости, отсутствие поставщиков и корректность скоупов.
  4. Инъекция в runtime — Сгенерированный код выполняет инъекцию без рефлексии.
// Использование в коде
class MyApplication : Application() {
    lateinit var component: ApplicationComponent
    
    override fun onCreate() {
        super.onCreate()
        component = DaggerApplicationComponent.builder()
            .networkModule(NetworkModule())
            .build()
    }
}

// В активити
override fun onCreate(savedInstanceState: Bundle?) {
    (application as MyApplication).component.inject(this)
    super.onCreate(savedInstanceState)
    // repository уже готов к использованию
}

Дополнительные механизмы

  • Скоупы (@Singleton, @ActivityScope, @FragmentScope) для управления жизненным циклом объектов.
  • @Binds для абстрактных модулей, когда нужно связать интерфейс с реализацией.
  • @Qualifier (например, @Named) для разных поставщиков одного типа.
  • Subcomponents для иерархических графов зависимостей (например, отдельные графы для Activity).
  • Multibinding для предоставления коллекций зависимостей.

Преимущества структуры Dagger

  • Высокая производительность — нет рефлексии, весь код генерируется заранее.
  • Проверка на компиляции — ошибки в графе зависимостей обнаруживаются сразу.
  • Читаемость — явное объявление зависимостей через аннотации.
  • Тестируемость — легко заменять модули на тестовые.

Эта структура делает Dagger мощным, хотя и сложным для изучения, инструментом для управления зависимостями в крупных Android приложениях, обеспечивая чистую архитектуру и модульность кода.