Для генерации кода Hilt требуется доступ ко всем модулям Gradle, использующим Hilt. Модуль Gradle, который компилирует класс Application, должен содержать все модули Hilt и классы, внедренные через конструктор, в своих транзитивных зависимостях.
Если ваш многомодульный проект состоит из обычных модулей Gradle, вы можете использовать Hilt, как описано в статье Внедрение зависимостей с помощью Hilt. Однако это не относится к приложениям, в которых есть модули функций.
Hilt в модулях функций
В модулях функций зависимость модулей друг от друга обычно инвертирована. Поэтому Hilt не может обрабатывать аннотации в модулях функций. Для внедрения зависимостей в модулях функций необходимо использовать Dagger.
Чтобы решить эту проблему с модулями функций, необходимо использовать зависимости компонентов. Выполните следующие действия:
- Объявите интерфейс
@EntryPointв модулеapp(или в любом другом модуле, который может быть обработан Hilt) с зависимостями, необходимыми модулю функции. - Создайте компонент Dagger, который зависит от интерфейса
@EntryPoint. - Используйте Dagger в модуле функции как обычно.
Рассмотрим пример со страницы Внедрение зависимостей с помощью Hilt. Предположим, вы добавили в проект модуль функции login. Вы реализуете функцию входа
с помощью действия LoginActivity. Это означает, что вы можете получить привязки только из компонента приложения.
Для этой функции требуется OkHttpClient с привязкой authInterceptor.
Сначала создайте интерфейс @EntryPoint, установленный в SingletonComponent, с привязками, которые нужны модулю login:
Kotlin
// LoginModuleDependencies.kt - File in the app module. @EntryPoint @InstallIn(SingletonComponent::class) interface LoginModuleDependencies { @AuthInterceptorOkHttpClient fun okHttpClient(): OkHttpClient }
Java
// LoginModuleDependencies.java - File in the app module. @EntryPoint @InstallIn(SingletonComponent.class) public interface LoginModuleDependencies { @AuthInterceptorOkHttpClient OkHttpClient okHttpClient(); }
Чтобы выполнить внедрение через поле в LoginActivity, создайте компонент Dagger, который зависит от интерфейса @EntryPoint:
Kotlin
// LoginComponent.kt - File in the login module. @Component(dependencies = [LoginModuleDependencies::class]) interface LoginComponent { fun inject(activity: LoginActivity) @Component.Builder interface Builder { fun context(@BindsInstance context: Context): Builder fun appDependencies(loginModuleDependencies: LoginModuleDependencies): Builder fun build(): LoginComponent } }
Java
// LoginComponent.java - File in the login module. @Component(dependencies = LoginModuleDependencies.class) public interface LoginComponent { void inject(LoginActivity loginActivity); @Component.Builder interface Builder { Builder context(@BindsInstance Context context); Builder appDependencies(LoginModuleDependencies loginModuleDependencies); LoginComponent build(); } }
После выполнения этих шагов используйте Dagger в модуле функции как обычно. Например, вы можете использовать привязки из SingletonComponent в качестве зависимости класса:
Kotlin
// LoginAnalyticsAdapter.kt - File in the login module. class LoginAnalyticsAdapter @Inject constructor( @AuthInterceptorOkHttpClient okHttpClient: OkHttpClient ) { ... }
Java
// LoginAnalyticsAdapter.java - File in the login module. public class LoginAnalyticsAdapter { private final OkHttpClient okHttpClient; @Inject LoginAnalyticsAdapter( @AuthInterceptorOkHttpClient OkHttpClient okHttpClient ) { this.okHttpClient = okHttpClient; } ... }
Чтобы выполнить внедрение через поле, создайте экземпляр компонента Dagger с помощью applicationContext, чтобы получить зависимости SingletonComponent:
Kotlin
// LoginActivity.kt - File in the login module. class LoginActivity : AppCompatActivity() { @Inject lateinit var loginAnalyticsAdapter: LoginAnalyticsAdapter override fun onCreate(savedInstanceState: Bundle?) { DaggerLoginComponent.builder() .context(this) .appDependencies( EntryPointAccessors.fromApplication( applicationContext, LoginModuleDependencies::class.java ) ) .build() .inject(this) super.onCreate(savedInstanceState) ... } }
Java
// LoginActivity.java - File in the login module. public class LoginActivity extends AppCompatActivity { @Inject LoginAnalyticsAdapter loginAnalyticsAdapter; @Override protected void onCreate(Bundle savedInstanceState) { DaggerLoginComponent.builder() .context(this) .appDependencies( EntryPointAccessors.fromApplication( getApplicationContext(), LoginModuleDependencies.class ) ) .build() .inject(this); super.onCreate(savedInstanceState); ... } }
Дополнительную информацию о зависимостях компонентов в модулях функций можно найти в этой статье.
Подробнее об использовании Dagger в приложениях для Android…