Comenzando con daga-2

Ejemplo de Android

Una de las principales dificultades de escribir una aplicación de Android con Dagger es que el propio sistema operativo crea instancias de muchas clases del marco de trabajo de Android, como Activity y Fragment, pero Dagger funciona mejor si puede crear todos los objetos inyectados. En su lugar, debe realizar la inyección de miembros en un método de ciclo de vida. A partir de la versión 2.10, dagger permite usar dagger.android, lo que simplifica el uso de dagger con componentes de Android.

** Objetos de actividad de inyección **

  1. Instale AndroidInjectionModule en el componente de su aplicación para asegurarse de que todos los enlaces necesarios para estos tipos base estén disponibles.

     @Component(modules = {AndroidInjectionModule.class})
     public interface AppComponent {}
    
  2. Comience escribiendo un @Subcomponent que implemente [AndroidInjector][AndroidInjector], con un @Subcomponent.Builder que extienda [AndroidInjector.Builder][AndroidInjector.Builder]:

     @Subcomponent
     public interface MainActivityComponent extends AndroidInjector<MainActivity> {
         @Subcomponent.Builder
         abstract class Builder extends AndroidInjector.Builder<MainActivity> {}
     }
    
  3. Después de definir el subcomponente, agréguelo a su jerarquía de componentes definiendo un módulo que vincule el generador de subcomponentes y agregándolo al componente que inyecta su Aplicación:

     @Module(subcomponents = MainActivityComponent.class)
     public abstract class MainActivityModule {
    
         @Binds @IntoMap @ActivityKey(MainActivity.class)
         abstract AndroidInjector.Factory<? extends Activity>
         bindMainActivityInjectorFactory(MainActivityComponent.Builder builder);
     }
    
  4. A continuación, haga que su Aplicación implemente HasDispatchingActivityInjector y @Inject un DispatchingAndroidInjector<Activity> para regresar desde el método activityInjector():

     public class MyApp extends Application implements HasDispatchingActivityInjector     {
    
         @Inject
         DispatchingAndroidInjector<Activity> dispatchingActivityInjector;
    
         @Override
         public void onCreate() {
            super.onCreate();
            DaggerAppComponent.create().inject(this);
         }
    
         @Override
         public DispatchingAndroidInjector<Activity> activityInjector() {
             return dispatchingActivityInjector;
         }
     }
    
  5. Finalmente, en su método Activity.onCreate(), llame a AndroidInjection.inject(this) antes de llamar a super.onCreate();:

     public class MainActivity extends Activity {
         public void onCreate(Bundle savedInstanceState) {
             AndroidInjection.inject(this);
             super.onCreate(savedInstanceState);
         }
     }
    

Este ejemplo se basó en documentación oficial de la daga. La muestra de trabajo se puede encontrar en github

Descripción y configuración

¿Qué es Daga 2?

El sitio web se describe a sí mismo como:

Dagger es un marco de inyección de dependencia en tiempo de compilación completamente estático

La biblioteca facilita el modelado de gráficos de dependencia, así como la reutilización de objetos. Dado que la reflexión solo se usa en tiempo de compilación como parte del procesamiento de anotaciones, Dagger 2 ha mejorado la velocidad para la inyección de dependencia.

Configuración

1- Agregar soporte para el procesamiento de anotaciones:

Androide

Script build.gradle de nivel superior:

 repositories {
    mavenCentral()
  }
  dependencies {
    classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
  }

Script build.gradle de nivel de módulo:

apply plugin: 'com.neenbedankt.android-apt'

Java

plugins {
  id "net.ltgt.apt" version "0.5"
}    

2- Agregar las dependencias daga 2

 dependencies {
      compile 'com.google.dagger🗡2.x'
      apt 'com.google.dagger:dagger-compiler:2.x'
    }

Aprende Dagger2 con un ejemplo simple

He leído y visto muchos tutoriales diferentes de Dagger2, pero la mayoría de ellos son demasiado largos o difíciles de entender, así que decidí escribir un nuevo tutorial simple y breve para Dagger2, espero que les guste.

¿Por qué lo necesitamos?

  • Simplifica el acceso a instancias compartidas: proporciona una forma sencilla de obtener referencias a instancias compartidas, por ejemplo, una vez que declaramos en Dagger nuestras instancias únicas, como SharedPrefrences, podemos declarar campos con una simple anotación @Inject.
  • Pruebas unitarias y de integración más sencillas: podemos cambiar fácilmente los módulos que generan respuestas de red y simular este comportamiento.

Comencemos con un ejemplo simple

La fuente completa del ejemplo está disponible en mi cuenta de GitHub.

Agregar dependencias Dagger2

En primer lugar, debemos agregar las dependencias de Dagger2. Coloque el código debajo de su archivo build.gradle a nivel de módulo.

compile "com.google.dagger🗡$dagger_version"
compile "com.google.dagger:dagger-android:$dagger_version"
compile "com.google.dagger:dagger-android-support:$dagger_version"
annotationProcessor "com.google.dagger:dagger-compiler:$dagger_version"

Si recibe un error como Error: Conflicto con la dependencia ‘com.google.code.findbugs:jsr305’ en el proyecto ‘:aplicación’, debe agregar lo siguiente a su archivo principal app/build.gradle.

configurations.all {
   resolutionStrategy.force 'com.google.code.findbugs:jsr305:3.0.1'
}

Dos clases simples

Tenemos dos clases (vehículo y motor), la clase de vehículo necesita la clase de motor para funcionar y MainActivity necesita la clase de vehículo. Usaremos Dagger2 para proporcionar estas instancias.

class Vehicle {
   private Motor motor;

  @Inject
  Vehicle(Motor motor) {
     this.motor = motor;
  }

  void increaseSpeed(int value) {
     motor.accelerate(value);
  }

  void decreaseSpeed(int value) {
     motor.decelerate(value);
  }

  void stop() {
     motor.brake();
  }

  int getSpeed() {
     return motor.getRpm();
  }
}

Clase de motor:

class Motor {
  private int rpm;

  Motor() {
    this.rpm = 0;
  }

  int getRpm() {
    return rpm;
  }

  void accelerate(int value) {
    rpm += value;
  }

  void decelerate(int value) {
    rpm -= value;
  }

  void brake() {
    rpm = 0;
  }
}

Clase de módulo

La clase de módulo es responsable de proporcionar objetos que se pueden inyectar. En este ejemplo, queremos inyectar la clase Motor a la clase Vehicle e inyectar la clase Vehicle a MainActivity, por lo que debemos crear MyModule para proporcionar estas instancias.

@Module
class MyModule {

  @Provides
  @Singleton
  Motor provideMotor() {
    return new Motor();
  }

  @Provides
  @Singleton
  Vehicle provideVehicle() {
    return new Vehicle(new Motor());
  }
}

@Proporcionar anotación: el objeto devuelto por este método está disponible para inyección de dependencia.

@Interfaz de componentes

Dagger2 necesita una interfaz de componentes para saber cómo debe crear instancias de nuestras clases.

@Singleton
@Component(modules = {MyModule.class})
interface MyComponent {
  Vehicle provideVehicle();

  void inject(MainActivity main);
}

Interfaz @Component: conexión entre el proveedor del objeto y los objetos que expresan una dependencia.

Inyectar dependencia en Constructor

Al agregar la anotación @Inject, dagger2 puede crear automáticamente una instancia a partir de ese objeto como nuestro objeto Motor de ejemplo en la clase Vehicle.

Inyectar dependencia en MainClass

Dagger2 puede inyectar dependencias automáticamente en los constructores, pero los componentes de Android (actividades, fragmentos, etc.) son instanciados por el marco de trabajo de Android, lo que dificulta el uso de la inyección de dependencia en ellos, por lo que debemos inyectarlos manualmente como se muestra a continuación:

public class MainActivity extends AppCompatActivity {
  @Inject
  Vehicle vehicle;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    MyComponent component = DaggerMyComponent.builder().build();
    component.inject(this);
  }
}

Eso es todo, espero que lo disfruten.

Ejemplo básico

Definir un módulo (el modelo de dependencias y su gráfico):

@Module
public class CoffeeModule{

    @Provides
    public CoffeeMaker provideCoffeeMaker(){
         return new CoffeeMaker();
    }

    @Provides
    public Coffee provideCoffee(CoffeeMaker coffeeMaker){
        return new Coffee(coffeeMaker);
    }

}

Defina un componente:

@Component(
    modules={
        CoffeeModule.class
    }
)
interface CoffeeComponent {

        DeveloperActivity inject(DeveloperActivity developerActivity);
}

Inyectar las dependencias:

class DeveloperActivity extends ...{

    @Inject
    Coffee myCoffee;

    @Override
    protected void onCreate(Bundle savedInstanceState) {           
        super.onCreate(savedInstanceState);

        DaggerCoffeeComponent.builder()
                .coffeeModule(new CoffeeModule())
                .build()
                .inject();
       
    }

}