android dagger-2

Dagger 2.10 subcomponentes y constructores de Android



dagger-2 (2)

En resumen, se supone que debe anular la llamada a seedInstance en el seedInstance (que es una clase abstracta en lugar de una interfaz) para proporcionar otros módulos que necesita.

editar : Antes de hacerlo, verifique y asegúrese de que realmente necesita pasar ese Módulo. Como Damon agregó en una respuesta por separado , si está haciendo un Módulo específico para su clase de Android, puede confiar en la inyección automática de esa clase para extraer la configuración o instancia del gráfico en ese punto. Favorezca su enfoque si es más fácil simplemente eliminar los parámetros del constructor de su Módulo, lo que también puede proporcionar un mejor rendimiento ya que evitan instancias innecesarias y llamadas a métodos virtuales.

Primero, dagger.android en 30 segundos: en lugar de que cada Actividad o Fragmento conozca a su padre, la Actividad (o Fragmento) llama a AndroidInjection.inject(this) , que verifica la Aplicación para HasActivityInjector (o fragmentos, actividad y aplicación padre) para HasFragmentInjector ). La idea es que contribuyas con un enlace a un Map<Class, AndroidInjector.Factory> creado por Map<Class, AndroidInjector.Factory> , donde los enlaces contribuidos son casi siempre constructores de subcomponentes que escribes que crean subcomponentes específicos de objeto.

Como puede ver en AndroidInjection.inject(this) y AndroidInjector.Factory.create(T instance) , no tiene muchas oportunidades de pasar detalles específicos de la Actividad o del Fragmento a su Builder. En cambio, la idea es que su generador de subcomponentes anule la implementación de seedInstance . Como en los documentos para seedInstance :

Proporciona una instance que se utilizará en el gráfico de enlace del AndroidInjector integrado. Por defecto, esto se usa como un método BindsInstance , pero se puede anular para proporcionar cualquier módulo que necesite una referencia a la actividad.

Esta debería ser la misma instancia que se pasará a inject(Object) .

Eso se vería así:

@Subcomponent(modules = {OneModule.class, TwoModule.class}) public interface YourActivitySubcomponent extends AndroidInjector<YourActivity> { // inject(YourActivity) is inherited from AndroidInjector<YourActivity> @Builder public abstract class Builder extends AndroidInjector.Builder<YourActivity> { // Here are your required module builders: abstract Builder oneModule(OneModule module); abstract Builder twoModule(TwoModule module); // By overriding seedInstance, you don''t let Dagger provide its // normal @BindsInstance implementation, but you can supply the // instance to modules or call your own BindsInstance: @Override public void seedInstance(YourActivity activity) { oneModule(new OneModule(activity)); twoModule(new TwoModule(activity.getTwoModuleParameter())); } } }

La suposición aquí es que debe esperar la instancia de activity para los módulos. Si no es así, también tiene la opción de llamarlos cuando vincula el subcomponente:

@Provides @IntoMap @ActivityKey(YourActivity.class) AndroidInjector.Factory bindInjector(YourActivitySubcomponent.Builder builder) { return builder .oneModule(new OneModule(...)) .twoModule(new TwoModule(...)); }

... pero si puede hacer eso, entonces podría encargarse más fácilmente de esos enlaces anulando esos módulos, implementando un constructor de cero argumentos que pueda suministrar los parámetros del constructor del Módulo, y dejando que Dagger los cree como lo hace para cualquier Módulos con constructores públicos de cero argumentos.

Usando las nuevas clases (en 2.10) dagger.android, estoy tratando de inyectar cosas usando un Subcomponente que depende de otros Módulos, y, por lo tanto, tiene un Generador con setters para esos módulos. La documentación en https://google.github.io/dagger/android.html describe esto, pero no está claro sobre cómo escribir y / o invocar a esos creadores.

Citando desde el enlace de arriba:

AndroidInjection.inject () obtiene un DispatchingAndroidInjector de la Aplicación y pasa su actividad a inyectar (Actividad). DispatchingAndroidInjector busca el AndroidInjector.Factory para la clase de su actividad (que es YourActivitySubcomponent.Builder), crea el AndroidInjector (que es YourActivitySubcomponent) y pasa su actividad a inyectar (YourActivity).

Me parece que para poder llamar a los programadores para el Generador, ¿debo ingresar a algún lugar y asegurarme de que el Generador tenga todos los datos necesarios? El problema que veo es que en el tiempo de ejecución, obtengo una IllegalStateException: MODULE must be set , cuando AndroidInjector invoca el generador generado para mi Subcomponente.

El Subcomponente en cuestión es, de hecho, un Fragmento, no una Actividad, pero no estoy seguro de que eso importe. ¿Alguna idea sobre cómo hacer esto?


eso funciona, pero es innecesario. el método seedInstance proporciona la instancia de actividad en el gráfico, por lo que puede tener MyActivityModule sin estado y simplemente solicitar MyActivity en sus métodos @Provides.

class MyActivityModule { @Provides static SomethingDerivedFromMyActivity providesMethod(MyActivity myActivity) { return myActivity.somethingDerived(); } }

Hacer esto ahorra la instancia del módulo y permite que las fábricas generadas sean más ágiles.

de github.com/google/dagger/issues/615 .