2009-06-15 8 views
21

Quizás estoy ciego, pero no veo cómo utilizar Guice (acaba de empezar con él) para reemplazar la llamada new en este método:¿Cómo se usa Google Guice para crear objetos que requieren parámetros?

public boolean myMethod(String anInputValue) { 
    Processor proc = new ProcessorImpl(anInputValue); 
    return proc.isEnabled(); 
} 

Para la prueba de que podría haber una implementación diferente del procesador , así que me gustaría evitar la llamada new y, en el transcurso de eso, deshacerme de la dependencia de la implementación.

Si mi clase solo pudiera recordar una instancia de Processor, podría inyectarla a través del constructor, pero como los Processors están diseñados para ser inmutables, necesito uno nuevo cada vez.

¿Cómo podría lograr y lograr eso con Guice (2.0)?

Respuesta

27

Hace algún tiempo que uso Guice ahora, pero recuerdo algo llamado "inyección asistida". Le permite definir un método de fábrica donde se suministran algunos parámetros y algunos se inyectan. En lugar de inyectar el procesador, se inyecta una fábrica de procesadores, que tiene un método de fábrica que toma el parámetro anInputValue.

Te señalo al javadoc of the FactoryProvider. Creo que debería ser útil para ti.

+7

Sí, AssistedInject es la mejor solución. http://code.google.com/p/google-guice/wiki/AssistedInject –

+1

Aquí hay una breve publicación que escribí al respecto. La inyección asistida es una herramienta maravillosa para algunos problemas, y creo que no es tan conocida. Buen trabajo difundiendo el conocimiento. http://ripper234.com/p/assisted-injection-in-guice/ – ripper234

+0

¿Dónde puedo obtener el .jar para inyección asistida? No está disponible como descarga en http://code.google.com/p/google-guice/downloads/list. –

2

¿Necesita su procesador acceso a anInputValue durante todo su ciclo de vida? Si no es así, el valor podría ser aprobada en el método para llamar a que está usando, algo así como:

@Inject 
public MyClass(Processor processor) { 
    this.processor = processor; 
} 

public boolean myMethod(String anInputValue) { 
    return processor.isEnabled(anInputValue); 
} 
+0

Las implementaciones del procesador están diseñadas para ser inmutables, creándolas una vez con todos los datos que necesitan, y luego solo les piden cosas. –

9

Usted puede obtener el efecto deseado mediante la inyección de un "proveedor", que puede ser pedido en tiempo de ejecución para dar usted un procesador. Los proveedores proporcionan una forma de diferir la construcción de un objeto hasta que se solicite.

Están cubiertos en los Documentos de Guice here y here.

El proveedor se verá algo como

public class ProcessorProvider implements Provider<Processor> { 
    public Processor get() { 
     // construct and return a Processor 
    } 
} 

ya que los proveedores se construyen y se inyecta por Guice, ellos mismos pueden tener trozos inyectados.

Su código será algo como

@Inject 
public MyClass(ProcessorProvider processorProvider) { 
    this.processorProvider = processorProvider; 
} 

public boolean myMethod(String anInputValue) { 
    return processorProvider.get().isEnabled(anInputValue); 
} 
+0

Muchas gracias, esto parece ser lo que estaba buscando. A veces no ves el bosque por todos los árboles. –

+0

Y querrá vincular un DebugProcessorProvider de sus módulos de depuración, pero si ha estado utilizando Guice, probablemente ya lo haya descubierto. –

+1

Al ver que la API ahora ha cambiado a Process.isEnabled (anInputValue) (lo mismo que en mi respuesta), ¿por qué molestarse en incluir un proveedor ahora?¿Por qué no tener un solo procesador y omitir al proveedor por completo? – tddmonkey

Cuestiones relacionadas