Ключевым моментом в Hilt является то, что по умолчанию модули в исходном коде = модули, установленные в вашем приложении.
Вариант 1. Раздельные пути кода
В идеале у вас должны быть альтернативные модули для разных сборок, и отдельные из них используются через sourceSets
В исходном наборе релиза:
@InstallIn(ApplicationComponent::class)
@Module
object ReleaseModule {
@Provides
fun provideHttpClient(): OkHttpClient { /* Provide some OkHttpClient */ }
}
В исходном наборе отладки:
@InstallIn(ApplicationComponent::class)
@Module
object DebugModule {
@Provides
fun provideHttpClient(): OkHttpClient { /* Provide a different OkHttpClient */ }
}
Вариант 2: переопределить с помощью @BindsOptionalOf
Если вариант 1 невозможен, потому что вы хотите переопределить модуль, который все еще присутствует в источнике, вы можете использовать dagger необязательная привязка
@InstallIn(ApplicationComponent::class)
@Module
object Module {
@Provides
fun provideHttpClient(
@DebugHttpClient debugOverride: Optional<OkHttpClient>
): OkHttpClient {
return if (debugOverride.isPresent()) {
debugOverride.get()
} else {
...
}
}
}
@Qualifier annotation class DebugHttpClient
@InstallIn(ApplicationComponent::class)
@Module
abstract class DebugHttpClientModule {
@BindsOptionalOf
@DebugHttpClient
abstract fun bindOptionalDebugClient(): OkHttpClient
}
а затем в файле только в конфигурации отладки:
@InstallIn(ApplicationComponent::class)
@Module
object DebugHttpClientModule {
@Provides
@DebugHttpClient
fun provideHttpClient(): OkHttpClient { ... }
}
Вариант 3. Множественное связывание @IntoMap
Если вам нужна большая степень детализации, а не просто переопределение внедрения + тестирования / отладки, вы можете использовать множественные привязки и карты, используя ключ в качестве приоритета для выбора реализации.
@InstallIn(ApplicationComponent::class)
@Module
object Module {
@Provides
fun provideHttpClient(
availableClients: Map<Int, @JvmSuppressWildcards OkHttpClient>
): OkHttpClient {
// Choose the available client from the options provided.
val bestEntry = availableClients.maxBy { it.key }
return checkNotNull(bestEntry?.value) { "No OkHttpClients were provided" }
}
}
Основной модуль приложения:
@InstallIn(ApplicationComponent::class)
@Module
object MainModule {
@Provides
@IntoMap
@IntKey(0)
fun provideDefaultHttpClient(): OkHttpClient {
...
}
}
Переопределение отладки:
@InstallIn(ApplicationComponent::class)
@Module
object DebugModule {
@Provides
@IntoMap
@IntKey(1)
fun provideDebugHttpClient(): OkHttpClient {
...
}
}
Если вы используете вариант 3, я бы либо сделал предоставленный тип обнуляемым / необязательным, либо воздержался от использования @Multibinds
, чтобы что-то не удалось во время компиляции, а не во время выполнения, если ничего не привязано к карте
person
Stevie Kideckel
schedule
20.06.2020