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

Что такое Assisted Factory в Dagger?

2.7 Senior🔥 61 комментариев
#Dependency Injection

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

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

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

Что такое Assisted Factory в Dagger?

Assisted Factory — это паттерн и встроенная функция в Dagger 2, которая позволяет внедрять зависимости, часть которых предоставляется через DI-контейнер, а часть — динамически во время выполнения (например, параметры, известные только в рантайме). Это расширение классического паттерна "Assisted Injection", упрощающее его использование за счёт автоматической генерации фабричных классов.

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

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

  • Статические зависимости (из графа Dagger): например, Repository, Context, ApiService.
  • Динамические параметры (runtime-значения): например, userId, requestId, flags.

Прямое использование @Inject конструктора здесь невозможно, так как Dagger не может предоставить runtime-параметры. Assisted Factory решает эту проблему, разделяя ответственность: Dagger предоставляет то, что знает, а программист — то, что известно только в рантайме.

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

  1. Помечаем конструктор целевого класса аннотацией @AssistedInject.
  2. Помечаем runtime-параметры аннотацией @Assisted.
  3. Объявляем интерфейс фабрики с методом, принимающим assisted-параметры и возвращающим целевой класс. Помечаем его @AssistedFactory.
  4. Dagger автоматически генерирует реализацию этой фабрики, внедряя в неё статические зависимости.

Практический пример

Предположим, у нас есть UserViewModel, которому нужен UserRepository из графа и динамический userId.

// 1. Целевой класс с @AssistedInject
class UserViewModel @AssistedInject constructor(
    private val userRepository: UserRepository, // Статическая зависимость
    @Assisted private val userId: String        // Динамический параметр
) {
    fun getUser() = userRepository.getUser(userId)
}
// 2. Фабрика с @AssistedFactory
@AssistedFactory
interface UserViewModelFactory {
    fun create(userId: String): UserViewModel
}
// 3. Внедрение и использование фабрики
class UserActivity @Inject constructor(
    private val viewModelFactory: UserViewModelFactory
) {
    fun onCreate() {
        val userId = intent.getStringExtra("USER_ID") // Runtime-значение
        val viewModel = viewModelFactory.create(userId)
        // Работаем с viewModel...
    }
}

Dagger сгенерирует реализацию UserViewModelFactory, которая при вызове create(userId):

  • Возьмёт UserRepository из своего графа.
  • Передаст его вместе с userId в конструктор UserViewModel.

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

  • Упрощение кода: Не нужно писать фабрики вручную или использовать @BindsInstance в сложных сценариях.
  • Типобезопасность: Генерация происходит на этапе компиляции, ошибки обнаруживаются рано.
  • Чистое разделение ответственности: DI-контейнер управляет статическими зависимостями, клиентский код — динамическими.
  • Интеграция с ViewModel: Особенно полезно в Android с архитектурными компонентами, где ViewModel не может иметь параметров в конструкторе при использовании стандартных ViewModelProvider.Factory.

Отличие от классического Assisted Injection

В более ранних версиях Dagger использовался отдельный паттерн с @AssistedModule и @AssistedInject, где фабрику нужно было привязывать вручную. Assisted Factory (появился в Dagger 2.31+) — это эволюция этого подхода, где достаточно только @AssistedFactory интерфейса, а Dagger делает всю остальную работу автоматически.

Важные нюансы

  • Каждый @Assisted параметр должен иметь уникальный ключ (можно задать через @Assisted("key")), если типы повторяются.
  • Фабрика должна быть интерфейсом с одним методом, возвращающим тип с @AssistedInject.
  • Статические и динамические зависимости нельзя смешивать — все @Assisted параметры должны быть переданы в фабричный метод.
  • Assisted Factory идеально сочетается с ViewModel, когда нужен SavedStateHandle (как runtime-параметр) и другие зависимости из графа.

Заключение

Assisted Factory — это мощный и элегантный механизм Dagger для управления гибридными зависимостями, сочетающий преимущества compile-time безопасности и runtime-гибкости. Он значительно снижает шаблонный код, устраняя необходимость в ручном написании фабрик, и является предпочтительным способом реализации "assisted injection" в современных проектах на Dagger. Его использование делает код более чистым, тестируемым и соответствующим принципам чистой архитектуры, где зависимости явно разделены на статические и динамические.