2010-06-20 9 views
7

Espero redefinir o actualizar algunos enlaces dentro de un Módulo que a su vez es utilizado por un Inyector. Me doy cuenta de que los módulos son inmutables y una vez que se ha absorbido e inyectado un enlace, su definición no puede cambiar para todos los propósitos prácticos.Mejor enfoque para mutar (agregar/eliminar enlaces) un inyector Guice mientras mantiene el estado

Me gustaría agregar/cambiar/eliminar enlaces mientras mantengo singletons que ya viven en un inyector. Cambiar es un caso simple ya que uno puede lograr este efecto utilizando un Proveedor. Sin embargo, agregar o quitar dinámicamente una clave (definición de enlace) es un poco más complicado.

Cualquier idea si esto debe o puede hacerse prácticamente.

Pienso la mejor manera es volver a crear un inyector cada vez que un add/remove unión ocurre definiciones copia del original a la nueva, Cualquier únicos existentes sean definidas por ToInstance en lugar de con el tipo de aplicación, etc.

Respuesta

7

Se pueden usar inyectores para niños para lograr esto, pero requiere cierta configuración. Los inyectores de niños evitarán que las uniones de larga duración dependan de las de corta vida. Aquí hay un ejemplo:

class ForeverModule extends AbstractModule { 
    ... 
} 

class TemporaryModule extends AbstractModule { 
    ... 
} 

class Main { 
    public static void main(String... args) { 
     Injector foreverInjector = Guice.createInjector(new ForeverModule()); 

     Injector injector = foreverInjector.createChildInjector(
       new TemporaryModule()); 
     /* 
     * Do stuff with the injector as you would normally. When you 
     * get bored of that injector, create a replacement injector 
     * as a child of the long-lived injector. 
     */ 
    } 
} 

Los enlaces de Singleton en el módulo forever durarán mientras exista ese módulo. Los enlaces de Singleton en el módulo temporal durarán mientras uses el inyector correspondiente.

Advertencia: De forma predeterminada, se crearán enlaces just-in-time en el inyector de nivel superior. Si necesita un enlace de corta duración, debe vincular tanto la interfaz como la implementación en el módulo del inyector de su hijo. Que tiene este aspecto:

public void configure() { 
     bind(Foo.class).to(RealFoo.class); 
     bind(RealFoo.class); 
    } 
+0

supongo que sería hacer el trabajo si bien hay que planificar lo que pasa en lo módulo, por lo que las cosas están en módulos separados con el derecho de ser reemplazable a voluntad. –

+0

¿Cuáles son sus comentarios sobre la reconstrucción de un inyector desde cero copiando todas las vinculaciones del original (omitiendo los enlaces incorporados para c.g.i.Injector.class). ¿Hay alguna desventaja con este enfoque sobre la cascada y la inyección de fusión de createChildInjector? –

+0

Copiar enlaces de un módulo a otro realmente no funciona. Como mínimo, todos los ámbitos se restablecerán, violando su requisito de singleton. –

Cuestiones relacionadas