2010-10-21 9 views
12

Hay algo que no entiendo sobre el guice: de acuerdo con lo que he leído hasta ahora, se supone que debo usar el inyector solo en mi clase de arranque (en una aplicación independiente esto normalmente sería en el principal) método), como en el siguiente ejemplo (tomado de la documentación guice):¿Cómo evitar tener injector.createInstance() por todo el lugar cuando se usa guice?

public static void main(String[] args) { 
    /* 
    * Guice.createInjector() takes your Modules, and returns a new Injector 
    * instance. Most applications will call this method exactly once, in their 
    * main() method. 
    */ 
    Injector injector = Guice.createInjector(new BillingModule()); 

    /* 
    * Now that we've got the injector, we can build objects. 
    */ 
    RealBillingService billingService = injector.getInstance(RealBillingService.class); 
    ... 
    } 

Pero lo que si no todos los objetos que alguna vez necesita puede ser creado durante el arranque? Tal vez quiero responder a alguna interacción del usuario cuando la aplicación se está ejecutando? ¿No tengo que mantener mi inyector en algún lugar (por ejemplo, como una variable estática) y luego llamar a injector.getInstance (SomeInterface.class) cuando necesito crear un nuevo objeto?

Por supuesto, difundir llamadas a Injector.getInstance() por todas partes parece no ser deseable.

¿Qué me estoy equivocando aquí?

Respuesta

12

Sí, básicamente solo debe usar el inyector para crear obtener la instancia para el objeto raíz. El resto de la aplicación no debe tocar el contenedor de Guice. Como habrás notado, aún necesitas crear algunos objetos cuando sea necesario. Existen diferentes enfoques para hacer eso, cada uno adecuado para diferentes necesidades.

Inject a Provider Provider es una interfaz de Guice. Le permite solicitar una nueva instancia de un objeto. Ese objeto se creará usando Guice. Por ejemplo.

class MyService{ 
    private Provider<Transaction> transactionProvider; 
    public MainGui(Provider<Transaction> transactionProvider){ 
     this.transactionProvider = transactionProvider; 
    } 

    public void actionStarted(){ 
     Transaction transaction = transactionProvider.get(); 
    } 

construir una fábrica A menudo se necesita algún tipo de fábrica. Esta fábrica utiliza algunos servicios inyectados y algunos parámetros, y crea un nuevo objeto para usted. Luego usa esta fábrica para nuevas instancias. Luego inyectas esa fábrica y la usas. También hay ayuda para esto con el AssistedInject -extensión

Creo que con estas dos posibilidades, casi nunca se necesita usar el Guice-Injector. Sin embargo, a veces sigue siendo apropiado usar el inyector en sí. Luego puede inyectar el inyector a un componente.

3

Para ampliar la respuesta que publicó Gamlor, también debe diferenciar entre los tipos de objetos que está utilizando.

Para los servicios, la inyección es la solución correcta, sin embargo, no intente siempre hacer inyectables los objetos de datos (que generalmente son las hojas en su gráfico de objetos). Puede haber situaciones donde esa es la solución correcta, pero inyectar un Provider<List> probablemente no sea una buena idea. Un colega mío terminó haciendo eso, hizo que la base del código fuera muy confusa después de un tiempo. Acabamos de terminar de limpiar todo y los módulos de Guice son mucho más específicos ahora.

+0

Sí, estoy completamente de acuerdo con eso. – Gamlor

0

En resumen, creo que la idea general es que si responder a eventos de usuario es parte de las capacidades de su aplicación, entonces, bueno ...

BillingService billingService = injector.getInstance(BillingService.class); 
billingService.respondToUserEvent(event); 

supongo que podría ser un poco abstracto , pero la idea básica es que obtienes de Guice tu clase de aplicación de nivel superior. A juzgar por su pregunta, ¿creo que quizás BillingService no es su clase de nivel superior?

Cuestiones relacionadas