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:

//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.

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.

  • ¿Es posible a los miembros de @Inject (proporcionados a través de @Provides), que contienen un Contexto de Actividad de la Actividad Base
  • ¿Se puede hacer una inyección de daga en un método estático?
  • Android Espresso con Dagger
  • Alcance de la actividad Dagger2, ¿cuántos módulos / componentes necesito?
  • Dagger 2.2 método del módulo de constructor de componentes obsoleto
  • Dagger 2 inyecta error en AppCompatActivity
  • Dagger2 componente genérico método de inyección
  • Dagger 2: Error sobre subcomponentes, pero no tengo subcomponentes en mi aplicación
  • Inyectar base de datos en un ContentProvider con daga
  • Dagger 2, módulos de biblioteca y @Singleton
  • Dagger2 dagger.android. * Las clases no existen
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.