Pregunta

Tengo una aplicación MVP GWT utilizando actividades y lugares. Esto se inspira en la muestra de Mauro Bertapelle (en este hilo), aparentemente basado en algunos de Thomas Broyertrabajo.

Aquí está el problema: tengo LoginActivity, hacer una llamada RPC, que para un inicio de sesión exitoso devuelve un usuario. Este usuario tiene un rol (por ejemplo, administrador, usuario regular, invitado). Varias vistas y actividades, incluida una vista de Navigator, dependen de este papel para lo que muestran o hacen. ¿Cómo llevo esta instancia de usuario a las otras actividades?

No tengo un ClientFactory; La inyección (GIN) se usa para instancias de las opiniones en los administradores de actividades que proporcionan mis actividades/presentadores, y los administradores de actividades se inyectan en mi actividad. Entonces, esto puede reducirse a una pregunta de GIN: ¿Cómo obtengo la referencia del usuario donde se necesita? Esto parece ser similar a esta pregunta sobre referencias globales en MVP.

Considéreme un novato en ginebra, este es mi primer intento de usarlo. Supongo que hay una "forma de ginebra" para que esto suceda, pero no conozco a Gin lo suficientemente bien como para saber la mejor manera de hacerlo (si la ginebra debe usarse).

Muchas gracias.

Editar 1: A pesar de mis mejores esfuerzos buscando, así que para una pregunta similar, acabo de encontrar esta pregunta que es bastante idéntico al mío (¿es el algoritmo SO para encontrar enlaces "relacionados" mejores que la búsqueda?). Estoy pensando que la respuesta de Gin de David está en el camino correcto.

No creo que una solución de eventbus sea posible. Estoy siguiendo el Directrices de Google que implican instanciar actividad en cada cambio de lugar, por lo que un solo evento en sí mismo no será suficiente.

¿Fue útil?

Solución

Tenía requisitos similares en un proyecto reciente.

Cuando recibo una respuesta de RPC de inicio de sesión (o sesión), envío una autenticación personalizada EventBus. Todas las actividades que están interesadas en esto escuchan este evento. AuthenticationEvent tiene una referencia al objeto AppUser que es nulo si el usuario acaba de registrarse. AppUser contiene todos los datos necesarios (privilegios, grupos, etc.) para que las actividades puedan inspeccionarlos y actuar en consecuencia.

Acerca de las referencias globales: puede tener una clase con métodos estáticos que proporcionan datos que necesita. Esta clase tiene referencias de Singleton a las instancias necesarias. En mi ejemplo tengo método estático apputils.getCurrentUser (). Internamente tiene una referencia al Appuser y también escucha la autenticación para establecer/restablecer este campo.

Como nota al margen: no confíe en el lado del cliente para hacer cumplir las restricciones de acceso: debe separar sus servlets RPC en dos grupos: público y privado. Cualquier persona puede acceder a Public (esto es básicamente RPC de inicio de sesión/cierre de sesión y alguna otra información pública RPC), mientras que el RPC privado requiere que el usuario se autentique. Las restricciones de acceso se pueden establecer por ruta/servlet: http://code.google.com/appengine/docs/java/config/webxml.html#security_and_authentication

Actualizar:

  1. Como señaló, la clase con métodos estáticos no es aconsejable en esta configuración, porque no es reemplazable y esto evita la prueba (que es el objetivo de usar GIN).

  2. La solución es inyectar una clase de utilidad que contiene globales (apputils) en actividades que necesitan los globales. Los AppUtils deben declararse singleton en la configuración de GIN ya que una instancia es suficiente para toda la aplicación.

  3. Usar Provider o no es solo una pregunta si desea retrasar la inicialización de las dependencias (Apputil es dependencia). Dado que AppUtils es un singleton para toda la aplicación, no tiene sentido que se inicialice perezoso.

  4. A veces tendrá una situación en la que se muestran múltiples actividades en la pantalla (en mi caso era Menubar e Infobar). En este caso, cuando el usuario inicie sesión, necesitará una forma de notificarles el cambio. Use EventBus.

Otros consejos

Algo que estoy usando en el lado del servidor con Guice, y funcionaría igual de bien en el lado del cliente, es vincular a un proveedor personalizado. Sin embargo, en su caso, tendría que hacer del proveedor un singleton y empujar el valor en su devolución de llamada RPC (en lugar de sacarla de algún contexto). Primero necesitaría un proveedor específico:

@Singleton
public class CurrentUserProvider implements Provider<User> {
  private User currentUser;

  public User get() { return currentUser; }
  public void setCurrentValue(User currentUser) {
    this.currentUser = currentUser;
  }
}

Te unirías User al proveedor: bind(User.class).toProvider(CurrentUserProvider.class)En su devolución de llamada RPC inyectaría un CurrentUserProvider así que puedes setCurrentValue Pero en cualquier otro lugar inyectarías Provider<User> mantener CurrentUserProvider como detalle de implementación. Para objetos muy cortos, podría inyectar directamente un User valor en lugar de un Provider<User>.

Si necesita notificar a los objetos del cambio de valor, puede enviar un evento en el bus de eventos global.

Alternativamente, siempre puedes usar el concreto CurrentUserProvider tipo (que no tendría que implementar Provider más) y posiblemente hazlo un HasValueChangeHandlers Por lo tanto, podría registrar a los oyentes en él en lugar de en el autobús de eventos (pero tendría que limpiarse después de usted en sus actividades ' onStop y onCancel Para evitar fugas de memoria, mientras que se cuida automáticamente si registra manejadores en el bus de eventos en onStart).

(Si me preguntas, prefiero ir a autenticar desde la aplicación siempre que sea posible)

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