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

Что такое AssistedInject в Dagger?

3.0 Senior🔥 41 комментариев
#Dependency Injection#Архитектура и паттерны

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

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

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

Что такое AssistedInject в Dagger

AssistedInject — это дополнение к библиотеке Dagger, которое позволяет внедрять зависимости, часть которых предоставляется Dagger (через механизм внедрения), а часть — передаётся явно (вручную) в момент создания объекта. Это особенно полезно, когда некоторые параметры конструктора известны только во время выполнения, а не на этапе компиляции.

Проблема, которую решает AssistedInject

В классическом Dagger все зависимости для объекта должны быть предоставлены графом зависимостей на этапе компиляции. Однако часто возникают ситуации, когда объект требует параметры, которые:

  • Динамичны (например, идентификатор пользователя из Intent в Android).
  • Зависят от контекста выполнения.
  • Не могут быть известны во время компиляции и должны передаваться извне.

Раньше для этого приходилось создавать фабрики вручную или использовать другие обходные пути. AssistedInject решает эту проблему элегантно и с минимальным шаблонным кодом.

Как работает AssistedInject

  1. Аннотация @AssistedInject помечается на конструктор класса, который нуждается в "помощных" параметрах.
  2. Аннотация @Assisted используется для параметров конструктора, которые должны передаваться явно.
  3. Генерируемая фабрика: Dagger автоматически создаёт фабрику (Factory) для такого класса, которая принимает "помощные" параметры, а остальные зависимости получает из графа.

Пример использования AssistedInject

Рассмотрим типичный случай в Android — создание ViewModel, которой нужно передать идентификатор элемента.

Без AssistedInject пришлось бы создавать фабрику вручную:

class ProductViewModel(
    private val productId: String,
    private val repository: ProductRepository
) : ViewModel() { ... }

class ProductViewModelFactory(
    private val repository: ProductRepository,
    private val productId: String
) : ViewModelProvider.Factory {
    override fun <T : ViewModel> create(modelClass: Class<T>): T {
        return ProductViewModel(productId, repository) as T
    }
}

С AssistedInject код становится значительно проще:

// 1. Добавляем зависимость в build.gradle
// implementation 'com.google.dagger:dagger-assist:2.46' (включено в Dagger с версии 2.33)

// 2. Помечаем конструктор
class ProductViewModel @AssistedInject constructor(
    @Assisted private val productId: String, // Параметр, передаваемый явно
    private val repository: ProductRepository // Зависимость из графа Dagger
) : ViewModel() {

    // 3. Объявляем фабрику (интерфейс с аннотацией @AssistedFactory)
    @AssistedFactory
    interface Factory {
        fun create(productId: String): ProductViewModel
    }

    ... // Логика ViewModel
}

3. Внедрение фабрики в Activity/Fragment:

class ProductActivity : AppCompatActivity() {

    @Inject
    lateinit var viewModelFactory: ProductViewModel.Factory

    override fun onCreate(savedInstanceState: Bundle?) {
        (application as MyApp).appComponent.inject(this)
        super.onCreate(savedInstanceState)

        val productId = intent.getStringExtra("PRODUCT_ID")!!
        val viewModel = viewModelFactory.create(productId)
        // Используем viewModel
    }
}

Ключевые преимущества AssistedInject

  • Уменьшение шаблонного кода: Не нужно писать фабрики вручную.
  • Безопасность типов: Генерируемый код является типобезопасным.
  • Интеграция с Dagger: Полная совместимость с остальным графом зависимостей.
  • Поддержка Hilt: AssistedInject полностью работает с Hilt — официальной библиотекой для внедрения зависимостей в Android.
  • Гибкость: Можно комбинировать "помощные" параметры и зависимости из графа в любом порядке.

Ограничения и нюансы

  • Только для конструкторов: @Assisted можно применять только к параметрам конструктора.
  • Все или ничего: Если используется @AssistedInject, все "помощные" параметры должны быть помечены @Assisted.
  • Уникальные имена: В одном конструкторе все @Assisted параметры должны иметь уникальные имена или быть связаны через @Assisted("имя").
  • Не для всех объектов: Лучше всего подходит для объектов, создаваемых во время выполнения с динамическими параметрами (ViewModel, Presenter, UseCase и т.д.).

Альтернативы AssistedInject

  • Ручное создание фабрик (больше кода, но полный контроль).
  • Использование SavedStateHandle в Hilt для ViewModel (специальный случай для сохранения состояния).
  • Кастомные решения на Provider или Lazy.

Заключение

AssistedInject — мощное и элегантное решение для сценариев, когда объект требует смешанных зависимостей: часть из графа Dagger, часть — динамические параметры времени выполнения. Он значительно снижает количество шаблонного кода, улучшает читаемость и поддерживаемость, особенно в связке с Hilt для Android-разработки. Начиная с Dagger 2.33, эта функциональность включена в основную библиотеку, что подтверждает её важность и востребованность в реальных проектах.

Что такое AssistedInject в Dagger? | PrepBro