Daga 2 es elemental (Parte 2)

Parte anterior

Contenido

  1. Implementar métodos y campos.
  2. Inicialización retrasada en daga
  3. Daga módulos. Cuando la daga no te entiende
  4. Resumen nombrado. Múltiples instancias del mismo tipo

Implementar métodos y campos.

La primera parte describe un método para implementar la dependencia a nivel de constructor. Además, Dagger puede implementar dependencias para campos y métodos. Pero estas implementaciones deben usarse cuando sea absolutamente necesario.

Ejemplo de implementación del método:

class Car @Inject constructor(private var engine: Engine){ var key: Key? = null @Inject set } class Key @Inject constructor() 

En el ejemplo anterior, la dependencia del método set se implementa para el campo clave

La implementación de los campos se lleva a cabo en tres etapas:

  1. Agregar método de inserción a la fábrica abstracta
  2. Definir campos a implementar
  3. Usar métodos de implementación en una implementación de daga de clase abstracta para implementar dependencias

Claramente será más fácil entender esto, en orden

1. En nuestra clase abstracta, agregue un método de implementación para MainActivity

 @Component interface DaggerComponent { fun getCar(): Car fun getEngine(): Engine fun getFuel(): Fuel fun inject(act: MainActivity) } 

2. Defina los campos que deben implementarse en MainActivity. Los campos inyectados deben ser lateinit var y visibles para todos (público)

 @Injected lateinit var car: Car 

3. Llamamos al método agregado inject () de la clase abstracta para implementar los campos de actividad.

En última instancia, nuestra clase MainActivity se verá como un rastro. manera:

 class MainActivity : AppCompatActivity() { @Inject lateinit var car: Car override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) DaggerDaggerComponent.create().inject(this) } } 

Inicialización retrasada en daga

Como sabe, al iniciar una aplicación, no siempre se necesitan instancias de todas las clases. Esto acelera el primer lanzamiento y más. Hay dos tipos de inicialización de objetos incrustados en la daga: Proveedor <> y Lazy <>

Proveedor : la inicialización se produce en la primera llamada al objeto y con cada llamada se devolverá una nueva instancia del objeto
Lazy : la inicialización se produce en la primera llamada, luego se devuelven las instancias almacenadas previamente

Para usar estos tipos de inicialización, es necesario "envolver" los objetos inicializados en la forma deseada.

Ejemplo de uso del proveedor:

 class Engine @Inject constructor(private var fuel: Fuel){ fun start(){ if(fuel!=null){ print("Started!") }else{ print("No more fuel!") } } } class Car @Inject constructor(private var engine: Provider<Engine>){ var key: Key? = null @Inject set fun startCar(){ engine.get().start() } } class Key @Inject constructor() 

Cada vez que se llama al método get (), obtenemos una nueva instancia del objeto deseado.

Un ejemplo de uso de Lazy:

 class Fuel @Inject constructor() { val fuelType = if(BuildConfig.DEBUG){ "benzine" }else{ "diesel" } } class Engine @Inject constructor(private var fuel: Lazy<Fuel>){ fun start(){ if(fuel!=null){ print("Started with ${fuel.get().fuelType}") }else{ print("No more fuel!") } } } 

Cada vez que se llama al método get (), obtenemos la misma instancia.

Atencion Al agregar el método get () de la vista diferida en Android Studio, el método puede estar subrayado en rojo ya que Kotlin tiene su propia clase Lazy. Entonces importamos la clase daga

 import dagger.Lazy 

Daga módulos. Cuando la daga no te entiende

Hay momentos en que una daga no entiende tus intenciones. Por ejemplo, nuestra clase Car tiene un campo de tipo (interfaz) Driver, que es heredado por la clase Ivanov

Cuando intenta implementar un campo con un tipo de interfaz, obtiene el error "no se puede proporcionar sin un @ Anota los métodos anotados".

Para resolver este problema, dagger sugiere usar módulos. Los módulos proporcionan a la daga información adicional que no puede obtener por sí sola. Como módulos, puede usar interfaces u objetos (objeto).

Para resolver el problema anterior, cree un módulo:

 @Module interface DaggerModul { @Binds fun bindDriver(driver: Ivanov): Driver } class Ivanov @Inject constructor(): Driver 

En el método bindDriver, explicamos a Dagger cómo inicializar la interfaz.

También en el componente debe enumerar todos los módulos de dagas existentes

 @Component(modules = [DaggerModul::class]) interface DaggerComponent { … } 

Supongamos que para nuestro motor de clase se utiliza el campo del cilindro de biblioteca (interfaz) de terceros. ¿Cómo describir tal campo para la daga si no está claro qué clase se inicializará en tiempo de ejecución?

Hasta el momento, hemos usado anotaciones para explicar cómo dañar las dependencias. ¿Qué sucede si no sabe cómo crear clases a partir de bibliotecas extranjeras, por ejemplo?

Proporciona una anotación que describe los casos en los que necesita describir explícitamente una instancia de la clase que desea inicializar.

 @Module object DaggerModuleObject { @Provides @JvmStatic fun getBoschCylinder(): Cylinder = BoschCylinder() } 

Por lo tanto, le decimos a Dagger que al inicializar el campo del cilindro, necesitamos una instancia de la clase BoschCylinder.

Resumen nombrado . Múltiples instancias del mismo tipo

Hay momentos en los que necesita crear instancias de la misma clase con diferentes configuraciones. En nuestro ejemplo, estos son colores diferentes en el cuerpo y las puertas.

Al intentar construir un proyecto con un rastro. El módulo obtendrá el error "(nuestra clase) El color se enlaza varias veces"

 @Provides @JvmStatic fun getColorRed():Color = Color("red") @Provides @JvmStatic fun getColorBlue():Color = Color("blue") 

Para resolver estos casos, se utiliza la anotación con nombre . En primer lugar, en el módulo crearemos 3 nuevos métodos para la inicialización en daga

 @JvmStatic @Provides fun getColor(): Color = Color("") @Provides @Named("blueColor") @JvmStatic fun getColorBlue(): Color{ return Color("blue") } @JvmStatic @Named("redColor") @Provides fun getColorRed(): Color = Color("red") 

El primer método es el predeterminado, sin él la daga jurará sobre la ausencia de la clase "no se puede proporcionar sin un constructor Inject o un método anotado Provides"

Los siguientes dos métodos devuelven instancias de la misma clase. Queda por agregar la implementación de esta clase en los lugares correctos y llamar con la anotación Named

 class Door @Inject constructor() { @Named("blueColor") @Inject lateinit var color:Color } class Car @Inject constructor(private var engine: Provider<Engine>, private var door: Door, var driver: Driver){ var key: Key? = null @Inject set @Inject @Named("redColor") lateinit var color: Color fun startCar(){ engine.get().start() } } class Key @Inject constructor() 

Código fuente

Source: https://habr.com/ru/post/466769/


All Articles