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

Как заинжектить что-то в конструктор Viewmodel

2.0 Middle🔥 231 комментариев
#Android компоненты#Dependency Injection

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

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

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

Внедрение зависимостей в ViewModel с использованием Dagger Hilt

В современной Android-разработке рекомендуется использовать Dagger Hilt для инъекции зависимостей в ViewModel, так как это официальная библиотека от Google, упрощающая работу с Dagger.

Основные способы инъекции в ViewModel

1. Через конструктор ViewModel (предпочтительный способ)

Hilt автоматически обеспечивает зависимости через конструктор, если класс ViewModel аннотирован @HiltViewModel.

@HiltViewModel
class MyViewModel @Inject constructor(
    private val repository: DataRepository,
    private val analyticsService: AnalyticsService
) : ViewModel() {
    
    fun fetchData() {
        repository.getData()
        analyticsService.trackEvent("data_fetched")
    }
}

Для работы этого подхода необходимо настроить Hilt в проекте:

// В Application классе
@HiltAndroidApp
class MyApplication : Application()

// В Activity или Fragment
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
    
    private val viewModel: MyViewModel by viewModels()
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        viewModel.fetchData()
    }
}

2. Через кастомную фабрику ViewModel

Если вам нужно больше контроля над созданием ViewModel, можно использовать кастомную фабрику:

class CustomViewModelFactory @Inject constructor(
    private val repository: DataRepository,
    private val preferences: SharedPreferences
) : ViewModelProvider.Factory {
    
    override fun <T : ViewModel> create(modelClass: Class<T>): T {
        return MyViewModel(repository, preferences) as T
    }
}

// Использование в Activity/Fragment
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
    
    @Inject
    lateinit var viewModelFactory: CustomViewModelFactory
    
    private val viewModel: MyViewModel by viewModels { viewModelFactory }
}

3. Провайдинг зависимостей в модулях Hilt

Для того чтобы Hilt знал, как создавать зависимости, их нужно определить в модулях:

@Module
@InstallIn(ViewModelComponent::class)
object ViewModelModule {
    
    @Provides
    fun provideRepository(
        apiService: ApiService,
        database: AppDatabase
    ): DataRepository {
        return DataRepositoryImpl(apiService, database)
    }
    
    @Provides
    fun provideApiService(retrofit: Retrofit): ApiService {
        return retrofit.create(ApiService::class.java)
    }
}

Ключевые аспекты и лучшие практики

@HiltViewModel важные особенности:

  • ViewModel аннотированные @HiltViewModel автоматически привязаны к жизненному циклу компонента, в котором используются
  • Hilt генерирует необходимые фабрики ViewModel автоматически
  • Зависимости уничтожаются вместе с ViewModel

Область видимости зависимостей:

  • Зависимости, определенные в ViewModelComponent, живут столько же, сколько и сам ViewModel
  • Для разных сценариев используйте разные компоненты:
    • @ActivityScoped - для зависимостей, живущих пока живёт Activity
    • @FragmentScoped - для зависимостей Fragment
    • @ViewModelScoped - для зависимостей ViewModel

Пример с Assisted Injection для динамических параметров:

@HiltViewModel
class DetailViewModel @Inject constructor(
    private val repository: DataRepository,
    @Assisted private val itemId: String
) : ViewModel() {
    
    @AssistedFactory
    interface Factory {
        fun create(itemId: String): DetailViewModel
    }
}

Альтернативные подходы

Без Hilt можно использовать:

  1. Ручная инъекция через фабрику - как показано выше, но со своим графом зависимостей
  2. Koin - более легковесная библиотека для DI
  3. Kodein - еще одна альтернативная библиотека

Важные рекомендации:

  • Всегда предпочитайте инъекцию через конструктор для тестируемости
  • Избегайте инъекции контекста или объектов, связанных с жизненным циклом UI
  • Для сложных сценариев создавайте кастомные фабрики
  • Используйте @Qualifier аннотации для различения однотипных зависимостей

Правильная настройка DI в ViewModel обеспечивает чистую архитектуру, упрощает тестирование и делает код более поддерживаемым. Hilt значительно упрощает этот процесс по сравнению с чистым Dagger, автоматизируя большую часть шаблонного кода.

Как заинжектить что-то в конструктор Viewmodel | PrepBro