В поисках надежной, но простой структуры внедрения зависимостей (DI), не так давно я пришел к выводу, что Koin – это структура DI, которая отвечает моим требованиям. Также, на мой взгляд, Dagger – это де-факто основной фреймворк DI в Android, мощный и популярный – но его нельзя назвать простым. Затем пришел Hilt , который попадает в золотую середину. Это в значительной степени все тот же Dagger (со всей его скоростью и безопасностью во время компиляци), но переделанный во что-то более быстрое и легкое.
Я постараюсь дать очень быстрый обзор того, как использовать Hilt в вашем проекте. Я сделал это в одном из моих существующих проектов и был восхищен тем, насколько это просто.
Настройка
Hilt прост в использовании, потому что он выполняет много “магии” (то есть кодогенерации) “под капотом”. Чтобы начать его использовать, вам необходимо добавить обработчики аннотаций и другие зависимости в файл build.gradle
вашего проекта.
Обратитесь к официальной документации, так как вам понадобится довольно много дополнительной информации.
Зависимости
Чтобы сделать класс внедряемым, просто добавьте к конструктору аннотацию @Inject
.
class MyHelper @Inject constructor() { [...] }
Каждый раз, когда это выполняется, будет создан новый экземпляр. Для внедрения того же самого единственного экземпляра (который будет создан в первый раз), аннотируйте его – @Singleton
.
@Singleton class MyHelper @Inject constructor() { [...] }
Также доступна область видимости для views / фрагментов / активити/ view-models ( документация ). Это означает, что при запросе injections будет возвращен тот же экземпляр, если он находится в том же компоненте. Например, следующий класс будет создаваться каждый раз, когда он запрашивается из нового фрагмента:
@FragmentScoped class MyHelper @Inject constructor() { [...] }
Модули
Если у вас есть интерфейс и реализация, вам понадобится модуль. Думайте об этом как о инструкциях по созданию экземпляра класса. Для простого использования интерфейса / реализации используйте @Binds
.
@InstallIn(ApplicationComponent::class) abstract class MyHelperModule { @Binds abstract fun bindMyHelper(myHelperImpl: MyHelperImpl): MyHelper }
Для более сложных «инструкций» используйте @Provides
. Context
предоставляется по умолчанию, если вы добавляете аннотацию с помощью @ApplicationContext
или @ActivityContext
.
@Module @InstallIn(ApplicationComponent::class) object MyHelperModule { @Provides fun provideMyHelper( @ApplicationContext context: Context ) { [...] return MyHelper(context) } }
Место использования @InstallIn
вместе с вышеуказанной аннотацией области видимости, определяет, когда будет создан и предоставлен новый экземпляр вашего класса. Например, это создаст новый экземпляр MyHelper
для каждого Activity
, которое выполняет запрос:
@Module @InstallIn(ActivityComponent::class) abstract class MyHelperModule { @ActivityScoped @Binds abstract fun bindMyHelper(myHelper: MyHelperImpl): MyHelper }
Внедрение зависимостей
Теперь вы определили, какие у вас зависимости. Пришло время внедрить и использовать их.
Для ваших классов, которые вы можете создать, используйте конструктор с аннотацией @Inject
(как мы видели выше).
class MyHelper @Inject constructor(private val toBeInjected: AnotherHelper) { [...] }
Для системных классов, которые не инстанцируются вами (например, Activities, Fragments, Services), используйте аннотации @AndroidEntryPoint
, @Inject
и механизм lateinit
.
@AndroidEntryPoint class MyActivity : AppCompatActivity() { @Inject lateinit var myHelper: MyHelper [...] }
ViewModels
Для внедрения зависимостей ViewModel
из Android Jetpack нужен немного другой подход.
Сначала установите эти дополнительные зависимости .
Затем используйте @ViewModelInject
(вместо простого @Inject
) в конструкторе. Чтобы внедрить SavedStateHandle
, добавьте аннотацию @Assisted
. Наконец, нет необходимости в какой-либо фабрике ViewModel
, используйте by viewModels()
для извлечения ViewModel
вашего фрагмента или активити.
class MyViewModel @ViewModelInject constructor( @Assisted private val savedState: SavedStateHandle, private val myHelper: MyHelper, ) : ViewModel() { [...] }
Надеюсь, в этом коротком посте я дал вам некоторое представление о Hilt и о том, как его использовать. Глубокое погружение в документациию даст возможность для более подробного рассмотрения случаев использования. Удачного кодирования!
Источник