Cómo reemplazar dependencias dentro de Scopes en Dagger 2

¿Cómo puede anular las dependencias dentro de los diferentes ámbitos de Dagger 2? Ejemplo:

Tengo dos componentes en mi aplicación: ApplicationComponent y ActivityComponent . ApplicationComponent es el componente base y ActivityComponent es un componente del ámbito en el que desea realizar la anulación.

Para este ejemplo he creado esos modelos:

 public class Parrot { private final HelloPrinter helloPrinter; public Parrot(HelloPrinter helloPrinter) { this.helloPrinter = helloPrinter; } public void sayHello(){ helloPrinter.print(); } } public interface HelloPrinter { void print(); } public class AppHelloPrinter implements HelloPrinter{ @Override public void print() { System.out.println("Hello Application"); } } public class ActivityHelloPrinter implements HelloPrinter { @Override public void print() { System.out.println("Hello Activity"); } } 

Y el código:

 ApplicationComponent applicationComponent = DaggerApplicationComponent.builder().build(); applicationComponent.provideParrot().sayHello(); activityComponent = DaggerActivityComponent.builder() .applicationComponent(applicationComponent).build(); activityComponent.provideParrot().sayHello(); 

Mi salida deseada es:

 Hello Application Hello Activity 

Así que hice los módulos:

ApplicationModule:

 @Singleton @Component(modules = ApplicationModule.class) public interface ApplicationComponent { Parrot provideParrot(); } @Module public class ApplicationModule { @Provides @Singleton HelloPrinter providePrinter(){ return new AppHelloPrinter(); } @Provides Parrot provideParrot(HelloPrinter helloPrinter) { return new Parrot(helloPrinter); } } 

ActivityModule: Intentar anular el HelloPrinter

 @PerActivity @Component(dependencies = ApplicationComponent.class, modules = ActivityModule.class) public interface ActivityComponent { Parrot provideParrot(); } @Module @PerActivity public class ActivityModule { @Provides @PerActivity HelloPrinter provideHelloPrinter() { return new ActivityHelloPrinter(); } } 

Pero con esta configuración la salida es:

 Hello Application Hello Application 

¿Qué estoy haciendo mal? Gracias

La respuesta corta es … no puedes hacer eso.

Con la daga todo se hace en tiempo de compilación.

  1. Usted tiene un componente de aplicación, que sabe cómo construir un HelloPrinter y un Parrot .
    A continuación, exponga el Parrot para todos los componentes a utilizar.

  2. Usted tiene su componente de actividad, que también sabe cómo construir un HelloPrinter !

¿Así que lo que ocurre?

Tenga en cuenta el gráfico de objetos. Los componentes saben lo que pueden construir y dependen de otros componentes, exponiendo objetos conocidos ellos mismos.

 applicationComponent.provideParrot().sayHello(); 

Éste es fácil. Usted crea el componente, usted quiere un loro y se construye usando la impresora conocida.

 activityComponent.provideParrot().sayHello(); 

Lo que sucede aquí, es (básicamente) lo mismo. Dices que quieres un loro. Su componente de actividad no sabe cómo hacer una, sólo sabe cómo hacer una impresora!
Pero espera. Tiene una dependencia de un componente de aplicación, exponiendo convenientemente una Fábrica de Parrot .

La fábrica de componentes de la aplicación se llama y el loro se instancia. Dado que el módulo de aplicación sabe cómo construir una impresora, utiliza el que está a la mano.

…ahora que

Así que … usted podría proporcionar a los loros en su componente de actividad, que luego utilizaría una impresora diferente!

Gradle: error: Parrot se une varias veces

Aquí obtendríamos 2 loros en nuestro gráfico de objetos, ya que no hay "sobrescribir" sucediendo. Esto no funcionará, y no debería.

Conclusión

No hay forma de anular los métodos. Tan pronto como HelloPrinter un segundo Parrot o HelloPrinter fallará la compilación.

La única posibilidad de lograr una funcionalidad similar sería utilizar las anotaciones @Named() en qué impresora usar y / o tirar de la creación entera del loro hacia abajo en el módulo de actividad.

Y por favor, corrija si me falta algo, pero ni siquiera veo una manera de mantener la firma de la misma con el uso de anotaciones con nombre.

  • ¿Hay alguna biblioteca o algoritmo para convertir Shamsi (Jalali) a fecha gregoriana en Java?
  • Retrofit2 Condición de manejar cuando el código de estado 200 pero la estructura de json diferente a la clase de datamodel
  • Proyecto de limpieza no corrigiendo errores de R.java (Android)
  • Leer 3 elementos seleccionados al mismo tiempo
  • Error: la conversión al formato Dalvik falló: No se puede ejecutar dex:
  • Cómo comprobar mediante programación si la aplicación se está ejecutando en modo de depuración o no?
  • Cómo matar Android proceso si el usuario abre youtube
  • Cómo centrarse en ScrollView y LinearLayout
  • ¿Cuál es la mejor manera de serializar una imagen (compatible con Swing) de Java a Android?
  • Transición animada entre dos vistas de imagen
  • Java.lang.NoClassDefFoundError mientras ejecuta la prueba JUnit en Netbeans
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.