Ciclo de inclusión del módulo Dagger
Todavía soy nuevo en Dagger e intento conseguir una caída de cosas. Quería dividir mis módulos en grupos lógicos que cada uno proporcione su propia funcionalidad, pero básicamente actuaría igual que si estuviera en un Módulo.
Por ejemplo, digamos que tengo mi módulo de aplicación principal definido de la siguiente manera:
- Utilice los módulos Dagger sin la directiva "inyecta"
- Qué es exactamente la daga y cómo funciona
- Daga que no genera componentes para / clase de prueba
- ¿La manera más simple de crear un Singleton w / Dagger 2?
- Cómo inyectar una actividad en un adaptador usando dagger2
//com.example.android.MyAppModule.java @Module( includes = AnalyticsModule.class, injects = { <snip> } ) public class MyAppModule { // various provides }
Y tengo otro módulo definido como este que configura una interfaz ErrorReporter y proporciona la aplicación concreta a ella.
// com.example.android.analytics.AnalyticsModule.java @Module( addsTo = MyAppModule.class, injects = { MyApp.class } ) public class AnalyticsModule(){ // ErrorReporter is a public interface and ErrorReporterImpl is a package-local final concrete class that implements it @Provides @Singleton ErrorReporter providesErrorReporter(ErrorReporterImpl reporter) { return reporter }; }
En mi clase de aplicación, configuro el gráfico de objetos de la siguiente manera:
// com.example.android.MyApp.java public class MyApp extends Application { @Inject ErrorReporter errorReporter; @Override public void onCreate() { super.onCreate(); applicationGraph = ObjectGraph .create(new MyAppModule()) .plus(new AnalyticsModule()); applicationGraph.inject(this); errorReporter.initialize(); } }
Cuando ejecuto el compilador daga consigo algo como esto:
Graph validation failed: Module Inclusion Cycle: 0. com.example.android.analytics.AnalyticsModule included by com.example.android.MyAppModule 1. com.example.android.modules.MyAppModule included by com.example.android.analytics.AnalyticsModule 0. com.example.android.analytics.AnalyticsModule
¿Qué estoy haciendo mal aquí? Supongo que tiene algo que ver con includes / addsTo, pero cuando elimino los que obtengo otros errores.
Si quito includes = AnalyticsModule.class de MyAppModule consigo algo como esto:
com.example.android.analytics.ErrorReporter could not be bound with key com.example.android.analytics.ErrorReporter required by com.example.android.MyApp for com.example.android.MyAppModule
Todo está bien si renuncio por completo a un AnalyticsModule y luego entrego el método provideErrorReporter a MyAppModule, pero entonces tengo que hacer pública mi clase de impl concreta para poder usarla en el otro módulo.
- Campo no inyectado en el proyecto Android Dagger
- Componente Dagger2 con más de una dependencia
- ¿Es posible usar Dagger en el proyecto de la biblioteca?
- Cómo usar daga en un proyecto de biblioteca de Android
- Dagger: la clase no podría estar enlazada con la clave
- Dagger 2: Proporcionar la misma instancia entre múltiples componentes con el mismo alcance en diferentes módulos de biblioteca
- Dagger 2 - módulos de diferentes componentes
- ¿Cómo anula un módulo / dependencia en una prueba de unidad con Dagger 2.0?
addsTo=
está ahí para especificar que este gráfico es una extensión al módulo referenciado en un gráfico padre / hijo. .plus () es la versión en tiempo de ejecución de esto. Sólo necesita .plus () si tiene instancias administradas por gráficos de vida más corta. Esto corresponde aproximadamente a la noción de "alcance" en Guice y otros contenedores DI.
En su ejemplo usted está haciendo:
applicationGraph = ObjectGraph .create(new MyAppModule()) .plus(new AnalyticsModule());
Esto termina creando dos gráficos en una relación padre / hijo, que no es lo que necesita aquí. EN una aplicación para Android, quieres un gráfico para la Aplicación.
Simplemente puede eliminar addsTo y MyAppModule instanciará automáticamente AnalyticsModule, o puede pasar ambos en si desea evitar la inicialización dinámica de la siguiente manera:
applicationGraph = ObjectGraph.create(new MyAppModule(), new AnalyticsModule());
El ciclo de inclusión de módulos se debe a que tiene una relación cíclica entre estos dos módulos y los módulos deben formar ellos mismos un gráfico acíclico de configuración. MyAppModule incluye AnalyticsModule que a su vez incluye MyAppModule. (AddsTo es un menos riguroso includes = usado para especificar las cosas obtenidas de los gráficos principales)
@Module(includes = AnalyticsModule.class)
es útil para componer varios módulos en un módulo. En este caso, usar .plus(new AnalyticsModule())
es incorrecto porque AnalyticsModule
ya ha sido incluido por la línea includes
en la anotación. Por lo tanto, debe quitar la llamada a plus()
.
@Module(addsTo = MyAppModule.class)
es para permitir una llamada a .plus(new AnalyticsModule())
. Ya que hemos eliminado esa llamada, debemos eliminar el addsTo
también.
@Module(complete = false)
es necesario para AnalyticsModule
porque algunas de sus dependencias no pueden ser satisfechas por sí mismas. Esto está bien; Siempre y cuando MyAppModule
haya complete = true
(el valor predeterminado), Dagger realizará la comprobación de error necesaria.
Es cierto que el error del "Módulo de inclusión" fue un poco incierto. El ciclo fue causado por A incluyendo B que añade a A.