Muy buenas, soy Miguel y aquí les traigo otro nuevo artículo.
Índice
¿Qué es la inyección de dependencia?
La inyección de dependencia (DI) se está utilizando ampliamente en programación desde hace bastante tiempo. DI es una técnica mediante la cual una clase recibe otros objetos de los que depende en lugar de crearlos por sí misma.
La implementación de la inyección de dependencias le brinda las siguientes ventajas:
- Reutilización del código.
- Facilidad de refactorización.
- Facilidad de prueba.
Fundamentos de la inyección de dependencia
Al desarrollar una aplicación, una clase puede requerir referencias a otras clases. Por ejemplo, una clase Car
puede necesitar una referencia de una clase Engine
.
Estas clases requeridas se denominan dependencias y, en este ejemplo, la clase Car
depende de tener una instancia de la clase Engine
para ejecutar. Podemos proporcionar estas dependencias necesarias de tres formas diferentes:
- La clase dependiente crea las instancias u objetos de dependencias dentro de ella. En nuestro caso, creando el objeto de clase
Engine
dentro de la claseCar
. - Usando los objetos de otro lugar. La forma en que usamos
Context
ygetSystemService()
getters. - Proporcionar dependencias como parámetros a clases dependientes. En nuestro caso, pasar el objeto
Engine
como parámetro a la claseCar
a través de funciones de constructor o de establecimiento.
DI
es ideal para el desarrollo de Android. Si alguna vez ha utilizado Dagger
, el marco oficial de DI
o cualquier otra biblioteca DI
para Android, sabrá cuánto esfuerzo y código repetitivo se necesitaría para crear todas las dependencias requeridas manualmente.
Para mí, al principio de usar Dagger, era como una pesadilla entender e implementar las cosas. Se necesitaron muchos días para comprender las cosas y mucho más para implementarlas de manera eficiente.
Introducción a Dagger-Hilt
Debido a la cantidad de código repetitivo y al nivel de dificultad de implementación en las bibliotecas DI actuales, el equipo de Android ha creado Hilt.
Hilt proporciona una forma estándar de implementar DI en aplicaciones de Android al proporcionar contenedores para cada clase de Android en nuestro proyecto y administrar sus ciclos de vida automáticamente.
Hilt se construyó sobre Dagger para reducir el esfuerzo de realizar DI manual en el proyecto y obtener beneficios de la corrección en tiempo de compilación, el rendimiento en tiempo de ejecución, la escalabilidad, etc.
Hilt es una forma simplificada de Dagger para DI en aplicaciones de Android con muchos más beneficios.
Como la mayoría de nosotros ahora somos adoptados por los componentes de Jetpack, Hilt es ahora la biblioteca recomendada de Jetpack para la inyección de dependencias en Android.
Hilt fue desarrollado para Android con la intención de ahorrar tiempo a los desarrolladores.
¿Por qué Hilt?
El objetivo principal de Hilt es simplificar la infraestructura relacionada con Dagger para aplicaciones de Android. Los beneficios de Hilt son:
- Plantilla reducida.
- Dependencias de construcción desacopladas.
- Configuración simplificada.
- Pruebas mejoradas.
Fundamentos de la empuñadura
Antes de comenzar con la implementación, revisemos la terminología relacionada con Hilt. Al igual que Dagger, Hilt es un marco completamente basado en anotaciones. Algunas anotaciones que usamos con frecuencia son:
Esta anotación debe aplicarse a la clase de aplicación para que se genere el componente. ¿No es tan fácil comparado con Dagger?
@HiltAndroidApp class ExampleApplication : Application() { ... }
Esta anotación debe aplicarse a los componentes de Android como fragmentos, actividades, etc. para inyectar las dependencias.
@AndroidEntryPoint class ExampleActivity : AppCompatActivity() { ... }
Hilt actualmente admite las siguientes clases de Android:
-
Activity
. -
Fragment
. -
View
. -
Service
. -
BroadcastReceiver
.
Esta anotación se utiliza para realizar la inyección. Se utiliza para inyectar las dependencias en clases dependientes. Las dependencias se pueden inyectar a través de un constructor, campo o método. Esto es similar en Dagger.
@AndroidEntryPoint class ExampleActivity : AppCompatActivity() { @Inject lateinit var analytics: Analytics ... }
Inyección de campo.
class SampleAdapter @Inject constructor( private val service: SampleService ) { ... }
Inyección de construcción.
Los campos inyectados por Hilt no pueden ser privados.
Esta anotación se usa por encima de la clase donde proporcionamos dependencias, es decir, donde creamos objetos. Esto es similar en Dagger.
El módulo Hilt anotado con @InstallIn(ActivityComponent::class)
porque queremos que Hilt inyecte esa dependencia en la clase Activity
.
Esta anotación significa que todas las dependencias en este Module
están disponibles en todas las actividades de la aplicación.
@Module @InstallIn(ActivityComponent::class) abstract class ExampleModule { .... .... }
La anotación se usa en los módulos y encima de los métodos donde creamos objetos para pasarlos como dependencias.
Esta anotación es similar a la de Dagger. Se utiliza principalmente para proporcionar instancias de bibliotecas de terceros.
@Module @InstallIn(ActivityComponent::class) object NetworkModule { @Provides fun provideExampleService(): ExampleService { return Retrofit.Builder() .baseUrl("https://example.com") .build() .create(ExampleService::class.java) } }
Configuración de empuñadura
Primero, agregue el complemento hilt-android-gradle-plugin
al archivo build.gradle
de nivel raíz de su proyecto :
A continuación, aplique el complemento de Gradle en el archivo app/build.gradle
:
apply plugin: 'dagger.hilt.android.plugin' android { ... }
Finalmente, agregue las siguientes dependencias en el archivo app/build.gradle
:
dependencies { ... implementation "com.google.dagger:hilt-android:$hilt_version" kapt "com.google.dagger:hilt-android-compiler:$hilt_version" }
Se realizó la configuración del entorno para comenzar a usar Hilt. Una vez que construimos y sincronizamos el proyecto, podemos usarlos. ¡Comencemos a usar Hilt!
Empuñadura en acción
Veamos cómo inyectar una clase simple en la clase Aplicación.
class ExampleClass @Inject constructor() { fun doSomeWork() { Log.d("HiltApp", "Do some work") } } //Injecting the above ExampleClass into application @HiltAndroidApp class ExampleApplication : Application() { @Inject lateinit var exampleClass: ExampleClass @Override public void onCreate() { super.onCreate(); // Injection happens in super.onCreate() // Use exampleClass } }
Para decirle a Hilt cómo proporcionar instancias de un tipo, agregue la anotación @Inject
al constructor de la clase que desea inyectar.
La información que Hilt tiene sobre cómo proporcionar instancias de diferentes tipos también se denomina enlaces.
Una vez que hayamos habilitado la inyección de miembros en nuestro Application
, podemos comenzar a habilitar la inyección de miembros en nuestras otras clases de Android usando la anotación @AndroidEntryPoint
.
@AndroidEntryPoint class SampleActivity : BaseActivity() { @Inject lateinit var exampleClass: ExampleClass // Bindings in ActivityComponent override fun onCreate() { // Injection happens in super.onCreate(). super.onCreate() // Do something with exampleClass ... } }
Empuñadura viene con soporte Jetpack
Como la mayoría de nosotros comenzamos a usar las bibliotecas Jetpack, el soporte de Hilt para Jetpack necesita algunas dependencias adicionales.
Hilt actualmente admite los siguientes componentes de Jetpack:
-
ViewModel
. -
WorkManager
.
Echemos un vistazo a la creación de ViewModel
simple e inyectándolo en una actividad. @ViewModelInject
.
La anotación se usa en el constructor del objeto ViewModel
para proporcionar una instancia de ViewModel
.
class SampleViewModel @ViewModelInject constructor( private val sampleRepo: SampleRepo ): ViewModel { ... }
La inyección de este ViewModel
en Activity
es mucho más simple con una sola línea de código:
private val sampleViewModel: SampleViewModel by viewModels()
viewModels()
es una función delegada que se puede utilizar para inyectar un ViewModel
. Aquí no es necesario utilizar la anotación @Inject
.
Si queremos usar el Activity
nivel ViewModel
, necesitamos aplicar la función activityViewModels()
de delegado en lugar de viewModels()
.
Toda la actividad puede verse así:
@AndroidEntryPoint class ExampleActivity : AppCompatActivity() { private val sampleViewModel: SampleViewModel by viewModels() ... }
Obtenga más información sobre la compatibilidad con Jetpack en los documentos.
¿No es divertido inyectar los componentes de la forma más sencilla? Las personas que comenzaron a usar versiones iniciales de Dagger entenderían lo fácil que era usar Hilt en comparación con Dagger.
Sin embargo, era una capa superpuesta sobre Dagger, saber lo básico siempre es algo importante. Empiece a usar Hilt.
Por favor déjeme saber sus sugerencias y comentarios. Gracias por leer.
Añadir comentario