Pregunta

Tengo una aplicación web que usa Gin para inyectar dependencias en el punto de entrada.

private InjectorService injector = GWT.create(InjectorService.class);

@GinModules({PlaceContollerInject.class, RootViewInject.class})
public interface InjectorService extends Ginjector {

  RootView getRootView();
  PlaceController getPlaceConroller();

}

public class RootViewInject extends AbstractGinModule {

  @Override
  protected void configure() {
    bind(RootView.class).to(RootViewImpl.class);
  }
}

Necesito una versión móvil que use una implementación de RootView diferente. Las dependencias se describen en el siguiente módulo

public class RootViewMobileInject extends AbstractGinModule {

  @Override
  protected void configure() {
    bind(RootView.class).to(RootViewMobileImpl.class);
  }
}

La pregunta es cómo elegir la dependencia necesaria condicionalmente si necesitamos una versión móvil o predeterminada. He visto Gwt-gin múltiples implementaciones, pero no he descubierto esa solución porque el proveedor rompe la cadena de dependencias y el patrón de fábrica rompe la capacidad de prueba. En el video "Big Modular Java with Guice" aquí (12 minutos) El inyector de Guice con módulos se presentó como un reemplazo a las fábricas. Entonces, mi pregunta es si crea diferentes ginjectores para versiones móviles y predeterminadas (como MobileFactory y DefaultFactory) de mi aplicación o sería una mala práctica y debería configurar una instancia de ginjector con todas las versiones necesarias. Por ejemplo, con los enlaces de anotación como este.

public class RootViewMobileInject extends AbstractGinModule {

  @Override
  protected void configure() {
    bind(RootView.class).annotatedWith(Mobile.class).to(RootViewMobileImpl.class);
  }
}

y use enlaces anotados @Mobile en el punto de entrada GWT

  @Inject
  private void setMobileRootView(@Mobile RootView rw) {
    this.rw = rw;
  }

En un ejemplo tan simplificado como el anterior podría ser posible. Pero si una aplicación tiene más dependencias que necesitan versiones móviles y predeterminadas. Se parece a las fábricas de "feo" incalentables (como se dijo en la presentación de Guice). Lo siento por mi ingles. Se agradece cualquier ayuda.

¿Fue útil?

Solución

Creo que querrá usar la vinculación diferida GWT, utilizando el reemplazo de clase para unir una versión diferente de su servicio inyectorSe dependiendo del agente de usuario. Esto asegurará que la versión móvil solo tenga las implementaciones móviles compiladas (y descargadas)

Por lo tanto, tendría inyectorServateSktop, inyectorServiceMobile, que se extienden desde inyectorService, luego gwt.create (inyectorService.class) y dejan que la unión diferida decida qué implementación debe usar.

http://code.google.com/webtoolkit/doc/latest/devguidecodingbasicsdeferred.html#replacation

Una instancia de ginjector con todas las versiones parece mala, ya que significa que todo el código para ambas versiones siempre se descarga (y ciertamente no desea descargar todas sus vistas de escritorio en su aplicación móvil)

Editar: como señala Thomas en los comentarios, ya que los inyectores son clases generadas, deberá colocar cada inyectorServicexxx dentro de una clase de soporte simple que Gwt.Create () es el inyectorServicexxx, y usar reemplazo para cambiar entre los soportes.

Otros consejos

Hacer lo que desea es realmente bastante complicado porque su interfaz de inyector común, que se anota con su módulo de ginebra, no puede apuntar a un módulo de ginebra abstracto. El módulo de ginebra apuntado por la interfaz de su ginjector debe ser concreto. Un módulo concreto no puede satisfacer múltiples configuraciones al mismo tiempo.

Entonces, lo que hace es: (a) Cree su interfaz Ginjector, digamos Clientginjector y su módulo, ClientModule, para una aplicación de escritorio.

(b) Cree una segunda interfaz ginjector, digamos ClientGinjectortableTet, extendiendo la que creó (a) pero con una anotación de ginmodule que apunta a un módulo diferente, digamos ClientModuletablet.

- Ahora tiene dos interfaces de Ginjecor, uno y una secundaria predeterminada para tabletas, cada una apuntando a un módulo con sus propias implementaciones Configure ().

(c) Ahora desea crear fábrica para obtener su implementación correcta de ginjector. Puede hacer esto porque el ginjector en el que se burló (a) y (b) tienen un demonitador común que es la interfaz predeterminada creada en (a). Por lo tanto, crea una facotria abstracta con un método como este: public abstract Clientginjector getInjector (); Usted crea dos clases de concreto para niños uno para obtener el escritorio/ginjector predeterminado y otro para obtener el ginjector de la tableta.

(d) Ahora configura el GWT.XML de su módulo, al igual que Google IO en YouTube, explica que debe obtener su facotry deseado durante el tiempo de ejecución, utilizando enlaces diferidos GWT para cada una de sus fábricas de ginyectores.

(e) En su punto de entrada, lo más frist no debe obtener un ginjector sino su fábrica para ginyectores que usan GWT diferido de enlace. Llama al método abstracto que devuelve un Cantenginector, su conjunto.

(f) El fracaso épico al final. Guice no le permitirá unir dos veces la misma clave (anotación de clase más), incluso si usa diferentes inyectores (uno para escritorio y otro para tableta). Parece que las definiciones de enlace clave son globales, tan pronto como tienes dos módulos que redefinen las mismas claves, ese es el final de la aventura.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top