support medium google compiler annotationprocessor android dependency-injection dagger

android - medium - Daga e inyecciones anidadas



dagger android support (4)

Estoy usando Dagger para inyectar dependencias en una aplicación de Android, y tropecé con un problema que no estoy del todo seguro de cómo resolverlo de una manera limpia.

Lo que intento lograr es instanciar ayudantes e inyectarlos dentro de mi actividad, y hacer que estos ayudantes también contengan miembros inyectados.

Que funciona

La actividad donde mi ayudante está siendo inyectado:

public class MyActivity extends Activity { @Inject SampleHelper helper; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ((MyApplication) getApplication()).inject(this); Log.i("debug", "helper = " + helper); Log.i("debug", "helper context = " + helper.context); } }

La aplicación que crea el gráfico de objetos:

public class MyApplication extends Application { private ObjectGraph graph; @Override public void onCreate() { super.onCreate(); graph = ObjectGraph.create(getModules()); } private Object[] getModules() { return new Object[] { new MyModule(this) }; } public void inject(Object target) { graph.inject(target); } }

La inyección funciona perfectamente cuando instalo directamente una clase SampleHelper, que a su vez recibe un contexto de aplicación inyectada:

@Singleton public class SampleHelper { @Inject public Context context; @Inject public SampleHelper() {} }

Con el siguiente módulo:

@Module( injects = { MyActivity.class }, complete = false, library = true ) public class MyModule { private final MyApplication application; public MyModule(MyApplication application) { this.application = application; } @Provides @Singleton Context provideApplicationContext() { return application; } }

Lo que no funciona

Sin embargo, cuando se separa la interfaz auxiliar de su implementación:

public interface SampleHelper { } @Singleton public class SampleHelperImpl implements SampleHelper { @Inject public Context context; @Inject public SampleHelperImpl() {} }

Y agrega esto al módulo de daga:

public class MyModule { ... // added this method @Provides @Singleton public SampleHelper provideSampleHelper() { return new SampleHelperImpl(); } ... }

El contexto no se inyecta en mi SampleHelperImpl, como hubiera esperado. Ahora, supongo que esto se debe a que SampleHelperImpl se instancia a través de una llamada de constructor directa en lugar de una llamada de constructor iniciada por inyección, porque MyModule # provideApplicationContext () ni siquiera se llama, así que supongo que me falta algo sobre Dagger (que es Probablemente, ya que mis experiencias DI anteriores solo incluían a Spring).

¿Alguna idea sobre cómo inyectar mi contexto en la implementación de mi ayudante inyectado, de una manera "limpia Daga"?

¡Muchas gracias!


En caso de que alguien esté interesado, al implementar un método @Provides en un módulo de daga, puede obtener instancias de objetos manejados con daga de esa manera:

@Provides @Singleton public SampleHelper provideSampleHelper(Context context) { SampleHelper helper = new SampleHelperImpl(); helper.setContext(context); return helper; }

Esto funciona, pero todavía siento que es un poco torpe, ya que tengo que llamar explícitamente a mis colaboradores setters (típicamente lo que quieres eliminar con la inyección).

(Esperaré un poco en caso de que alguien venga con una mejor solución)



(Se aplica a Dagger v1.0.1)

Asegúrese de estar usando la inyección de adaptador. Con la inyección reflectante, daga aparentemente no hace una inyección transitiva en objetos @Provides . Creo que esto es un error.


Esta es una pregunta bastante antigua, pero creo que lo que quieres es esto:

@Provides @Singleton public SampleHelper provideSampleHelper(SampleHelperImpl impl) { return impl; }

De esta forma, Dagger creará su SampleHelperImpl y, por lo tanto, lo inyectará.