Dagger no puede encontrar miembros inyectables en un módulo

Estoy usando Dagger para la inyección de la dependencia en un proyecto de Androide, y puedo compilar y construir la multa de la aplicación. El gráfico de objeto parece estar correcto y funcionando, pero cuando agrego dagger-compilador como una dependencia para obtener errores en tiempo de compilación, reporta algunos errores extraños:

[ERROR] error: No binding for com.squareup.tape.TaskQueue<com.atami \ .mgodroid.io.NodeIndexTask> required by com.atami \ .mgodroid.ui.NodeIndexListFragment for com.atami.mgodroid \ .modules.OttoModule [ERROR] error: No binding for com.squareup.tape.TaskQueue<com.atami \ .mgodroid.io.NodeTask> required by com.atami \ .mgodroid.ui.NodeFragment for com.atami.mgodroid.modules.OttoModule [ERROR] error: No injectable members on com.squareup.otto.Bus. Do you want to add an injectable constructor? required by com.atami. \ mgodroid.io.NodeIndexTaskService for com.atami.mgodroid.modules.TaskQueueModule 

El error de Otto se parece al que Eric Burke menciona en su presentación sobre la Anatomía de Android App acerca de no tener una anotación @Provides , pero como se puede ver a continuación lo hago.

Mis módulos Otto y TaskQueue son los siguientes:

 @Module( entryPoints = { MGoBlogActivity.class, NodeIndexListFragment.class, NodeFragment.class, NodeActivity.class, NodeCommentFragment.class, NodeIndexTaskService.class, NodeTaskService.class } ) public class OttoModule { @Provides @Singleton Bus provideBus() { return new AsyncBus(); } /** * Otto EventBus that posts all events on the Android main thread */ private class AsyncBus extends Bus { private final Handler mainThread = new Handler(Looper.getMainLooper()); @Override public void post(final Object event) { mainThread.post(new Runnable() { @Override public void run() { AsyncBus.super.post(event); } }); } } } 

 @Module( entryPoints = { NodeIndexListFragment.class, NodeFragment.class, NodeIndexTaskService.class, NodeTaskService.class } ) public class TaskQueueModule { private final Context appContext; public TaskQueueModule(Context appContext) { this.appContext = appContext; } public static class IOTaskInjector<T extends Task> implements TaskInjector<T> { Context context; /** * Injects Dagger dependencies into Tasks added to TaskQueues * * @param context the application Context */ public IOTaskInjector(Context context) { this.context = context; } @Override public void injectMembers(T task) { ((MGoBlogApplication) context.getApplicationContext()) .objectGraph().inject(task); } } public static class ServiceStarter<T extends Task> implements ObjectQueue.Listener<T> { Context context; Class<? extends Service> service; /** * Starts the provided service when a Task is added to the queue * * @param context the application Context * @param service the Service to start */ public ServiceStarter(Context context, Class<? extends Service> service) { this.context = context; this.service = service; } @Override public void onAdd(ObjectQueue<T> queue, T entry) { context.startService(new Intent(context, service)); } @Override public void onRemove(ObjectQueue<T> queue) { } } @Provides @Singleton TaskQueue<NodeIndexTask> provideNodeIndexTaskQueue() { ObjectQueue<NodeIndexTask> delegate = new InMemoryObjectQueue<NodeIndexTask>(); TaskQueue<NodeIndexTask> queue = new TaskQueue<NodeIndexTask>( delegate, new IOTaskInjector<NodeIndexTask>(appContext)); queue.setListener(new ServiceStarter<NodeIndexTask>( appContext, NodeIndexTaskService.class)); return queue; } @Provides @Singleton TaskQueue<NodeTask> provideNodeTaskQueue() { ObjectQueue<NodeTask> delegate = new InMemoryObjectQueue<NodeTask>(); TaskQueue<NodeTask> queue = new TaskQueue<NodeTask>( delegate, new IOTaskInjector<NodeTask>(appContext)); queue.setListener(new ServiceStarter<NodeTask>( appContext, NodeTaskService.class)); return queue; } } 

 /** * Module that includes all of the app's modules. Used by Dagger * for compile time validation of injections and modules. */ @Module( includes = { MGoBlogAPIModule.class, OttoModule.class, TaskQueueModule.class } ) public class MGoBlogAppModule { } 

El análisis completo del gráfico de Dagger funciona desde un módulo completo. Ie @Module (complete = true), que es el valor predeterminado. Debido a que es el valor predeterminado, dagger, por defecto, asumirá que todos los enlaces están disponibles desde ese módulo o los módulos que incluye de forma explícita.

En este caso, usted ha dado dos módulos que usted dice están completos, pero Dagger no tiene ninguna manera de atar estos juntos en tiempo de compilación sin una señal adicional. En resumen, sin OttoModule saber acerca de TaskQueueModule, el compilador intentará analizar OttoModule por su completitud declarada, y fallar, ya que no ahora sobre TaskQueueModule.

Modifique la anotación de OttoModule como tal:

 @Module( includes = TaskQueueModule.class, entryPoints = { MGoBlogActivity.class, NodeFragment.class, NodeActivity.class, NodeCommentFragment.class, NodeIndexTaskService.class, NodeTaskService.class } ) 

Y entonces Dagger sabrá que para que OttoModule esté completo, incluye el otro módulo como parte de su definición completa.

Nota: dagger-compilador no puede detectar que TaskQueueModule está allí en la vía de acceso de clase y sólo "saber" que el desarrollador pensaba que se utilizará con OttoModule sin esa señal adicional. Por ejemplo, es posible que tenga varios módulos que definen las colas de tareas y cuál seleccionaría? La declaración debe ser explícita.

  • Inyección de clase genérica con Dagger
  • Ampliación de ObjectGraph con módulo de sustitución
  • Cómo compartir Dagger2 Subcomponente entre activies
  • Singletons en Dagger 1.x
  • Dagger y inyecciones anidadas
  • Dagger 2 Tercera parte Inyección Android
  • Daga: Inyectar campo en el pojo proporcionado
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.