Muy buenas, soy Miguel y aquí les traigo otro nuevo artículo.
Una biblioteca de inyección de dependencias recomendada por Jetpack
Í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 Car
clase puede necesitar una referencia de una Engine
clase. Estas clases requeridas se denominan dependencias y, en este ejemplo, la Car
clase depende de tener una instancia de la Engine
clase 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
Engine
clase dentro de laCar
clase. - 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
Engine
objeto como parámetro a laCar
clase 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:
@HiltAndroidApp
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() { ... }
@AndroidEntryPoint
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
@Inject
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.
@Module
Esta anotación se usa por encima de la clase donde proporcionamos dependencias, es decir, donde creamos objetos. Esto es similar en Dagger.
@Instalar
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 { .... .... }
@Proporciona
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 hilt-android-gradle-plugin
complemento al build.gradle
archivo 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 app/build.gradle
archivo:
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 @AndroidEntryPoint
anotación.
@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 activityViewModels()
función 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.
Referencias
Inyección de dependencia con Hilt
Por favor déjeme saber sus sugerencias y comentarios.
Gracias por leer.
Añadir comentario