Anvil para Kotlin: guía completa con ejemplos prácticos
1. ¿Qué es Anvil y para qué sirve?
Anvil es una biblioteca de generación de código para Kotlin que funciona sobre los frameworks de inyección de dependencias (DI) Dagger y Hilt. Su objetivo principal es eliminar el trabajo repetitivo de escribir código boilerplate relacionado con módulos DI, componentes, fábricas y puntos de entrada. En lugar de crear y anotar manualmente los módulos de Dagger, simplemente marcas las clases con anotaciones de Anvil, y la biblioteca genera todo el código necesario durante la compilación.
¿Para qué sirve? En proyectos grandes de Android o Kotlin Multiplatform, la cantidad de clases que deben registrarse en el grafo de dependencias puede llegar a cientos. Agregar un nuevo módulo de Dagger cada vez, escribiendo @Provides o @Binds, es lento, propenso a errores y dificulta la refactorización. Anvil resuelve este problema automatizando la creación de módulos basándose en anotaciones simples. Esto es especialmente útil en arquitecturas basadas en módulos de funcionalidades (feature modules), donde cada módulo debe compilarse y probarse de forma independiente.
Anvil se integra estrechamente con Gradle y utiliza Kotlin Symbol Processing (KSP) o KAPT para generar código. Es compatible tanto con Dagger como con Hilt y funciona en proyectos multiplataforma. La biblioteca fue desarrollada por Square, conocida por sus herramientas para desarrollo Android (Retrofit, OkHttp, Moshi).
2. Instalación
Para instalar Anvil en tu proyecto Kotlin/Gradle, agrega las siguientes dependencias en el archivo build.gradle.kts (a nivel raíz del proyecto):
// En el build.gradle.kts raíz
plugins {
id("com.google.dagger.hilt.android") version "2.48" apply false
id("com.squareup.anvil") version "2.4.7" apply false
}
Luego, en el módulo de la aplicación (por ejemplo, app/build.gradle.kts):
plugins {
id("com.android.application")
kotlin("android")
id("com.google.dagger.hilt.android")
id("com.squareup.anvil")
}
android {
// ... tu configuración de Android
}
dependencies {
// Hilt
implementation("com.google.dagger:hilt-android:2.48")
kapt("com.google.dagger:hilt-compiler:2.48")
// Anvil
implementation("com.squareup.anvil:annotations:2.4.7")
ksp("com.squareup.anvil:compiler:2.4.7") // o kapt si no usas KSP
}
Si usas KSP en lugar de KAPT, asegúrate de tener el plugin KSP configurado:
plugins {
id("com.google.devtools.ksp") version "1.9.0-1.0.13"
}
Después de sincronizar Gradle, Anvil estará listo para usar.
3. Inicio rápido — ejemplo mínimo funcional
Veamos un ejemplo sencillo: tenemos una clase UserRepository que debe inyectarse en MainViewModel.
Paso 1. Crea la interfaz o clase que se inyectará:
// UserRepository.kt
class UserRepository @Inject constructor() {
fun getUser(): String = "Juan Pérez"
}
Paso 2. Crea la clase que usará la dependencia:
// MainViewModel.kt
class MainViewModel @Inject constructor(
private val userRepository: UserRepository
) {
fun getUserName(): String = userRepository.getUser()
}
Paso 3. Crea un componente Hilt (o Dagger) con Anvil:
// AppComponent.kt
@Singleton
@Component
@MergeComponent(AppScope::class) // Anotación de Anvil
interface AppComponent {
fun inject(app: MyApplication)
}
// AppScope.kt (definimos el ámbito)
@Scope
@MustBeDocumented
annotation class AppScope
Paso 4. Registra las clases en el grafo de dependencias con anotaciones de Anvil:
// UserRepository.kt (añadimos la anotación)
@ContributesBinding(AppScope::class)
class UserRepository @Inject constructor() {
fun getUser(): String = "Juan Pérez"
} También en la biblioteca
Envío de correo electrónico en Kotlin: bibliotecas y ejemplos de código
Trabajo con YAML en Java: bibliotecas SnakeYAML y Jackson
Limitación de Tasa en TypeScript: bibliotecas, estrategias y ejemplos
Trabajo con fechas en Kotlin: bibliotecas y herramientas para el desarrollo