Estoy trabajando en una aplicación de Android que sigue el patrón de arquitectura MVP. En todos mis fragmentos estoy inyectando un presentador. Por lo tanto, mis Fragmentos (Vistas) necesitan tener un Componente en el que declaro las inyecciones. Por ejemplo:

@ActivityScope
@Component(
        dependencies = AppComponent.class,
        modules = {
                PresenterModule.class,
                InteractorModule.class
        }
)
public interface ViewInjectorComponent {
    void inject(SelectEventOccurrenceFragment fragment);
    void inject(CreateOpponentFragment fragment);
    void inject(SelectOpponentFragment fragment);
    void inject(TeammatesInvitedFragment fragment);
    ...
}

Cada nueva Vista que agrego a mi Aplicación (Fragmento) debe tener su entrada declarada aquí. Me preguntaba si es posible generar este código automáticamente con algún tipo de procesador de anotaciones. La aplicación ya tiene varios fragmentos, este archivo componente tiene más de 300 entradas fácilmente. Sería increíble si pudiera hacer algo como:

@Injectable
public class MyNewFragment implements MyNewView {
...
}

Y luego genera automáticamente la entrada en el archivo ViewInjectorComponent. ¿Es posible? ¿Dónde debería mirar?

0
4gus71n 2 abr. 2017 a las 02:38

2 respuestas

La mejor respuesta

La situación que está experimentando puede ser una consecuencia de organizar sus Módulos y Componentes de una manera inusual. En particular, la agrupación lateral (un componente inyecta todos los presentadores) en lugar de verticalmente (un componente inyecta la funcionalidad relacionada con SelectOpponentActivity) es problemática.

Un buen ejemplo a seguir está en el Google Android Architecture Blueprints GitHub repo. Si examina el código allí, verá que tienen una funcionalidad organizada relacionada con las tareas dentro de un paquete de Java junto con un componente, módulo, presentador, etc. por separado. Esto tiene la ventaja de poder restringir la accesibilidad de los constructores de las clases contenido en el mismo y que cumple con el Elemento 13 efectivo de Java: Minimice la accesibilidad de las clases y los miembros.

Del mismo modo, ha agrupado todos sus módulos en un módulo de presentador y un módulo de interacción. El consejo de la documentación oficial de Dagger 2 es que organice los módulos primero para la capacidad de prueba y luego Lineas funcionales. Nuevamente, puede consultar el ejemplo de Blueprint para saber cómo hacer esto.

Finalmente, tenga en cuenta que, inevitablemente, hay una plantilla repetitiva involucrada en el uso de la mayoría de los marcos DI como Dagger 2. En cierto sentido, está intercambiando un problema mayor ("¿cómo trato con todos estos constructores?") Con problemas mucho más pequeños y más manejables ("cómo agrupo mis componentes", etc.).

Actualizar Hay una biblioteca llamada Auto Dagger2 que puede generar componentes para usted. Consulte este repositorio de Github. Aquí hay un ejemplo de una anotación:

@AutoComponent
@Singleton
public class ExampleApplication extends Application { 
}

Lo que genera el siguiente código:

@Component
@Singleton
public interface ExampleApplicationComponent { 
}

Consulte también Google Auto si está interesado en las herramientas de generación de código.

1
David Rawson 4 abr. 2017 a las 02:10

No estoy completamente seguro de que lo que voy a decir sea apropiado para una respuesta, pero me arriesgaré aquí.

Incluso si encuentra la manera de hacer lo que quiere, no lo haga en producción (está bien si solo quiere aprender técnicas de generación de código).

Los beneficios que obtiene de este enfoque son pequeños (no escribir varias líneas de código trivial), pero tenga en cuenta los inconvenientes:

  1. La lógica para la generación de código necesita ser escrita / depurada / mantenida
  2. Tal enfoque será una violación del "principio de mínimo asombro"
  3. La generación de código es MALA

Tenga en cuenta el tercer punto: lo digo en serio. El uso de la generación de código siempre conduce a una sobrecarga de mantenimiento, por lo tanto, debe usarse solo como último recurso.

Dagger por sí solo usa la generación de código, pero por una buena razón: el rendimiento. Sin embargo, el rendimiento no es un problema en su caso.

Para resumir: su idea es muy interesante, pero enfoques como este no deberían usarse para aplicaciones de producción (a menos que esta funcionalidad se agregue a Dagger de forma nativa).

0
Vasiliy 2 abr. 2017 a las 08:28