2013-02-08 12 views
5

Ho un semplice POJO:iniettando chiamato Guice Singleton

public class MyPOJO { 
    @Inject 
    private Fizz fizz; 

    private Buzz buzz; 

    // rest of class omitted for brevity 
} 

Vorrei configurare il mio modulo Guice tale che ci sono due tipi di Fizz ca che inietta:

  1. Uno speciale, globally-singleton Fizz istanza; e
  2. Altro (non speciale) Fizz casi

voglio MyPOJO da iniettare con la speciale istanza/Singleton. Così ho modificato il mio codice:

public class MyPOJO { 
    @Inject @Named("Special-Fizz") 
    private Fizz fizz; 

    private Buzz buzz; 

    // rest of class omitted for brevity 
} 

Poi, nel mio modulo:

public class MyModule extends AbstractModule { 
    @Override 
    public void configure() { 
     bind(Fizz.class).annotatedWith(
      Names.named("Special-Fizz")) 
      .to(Fizz.class); 

     // Other bindings here... 
    } 

    @Provides @Singleton 
    private Fizz providesFizz() { 
     return new Fizz(true, "Special", 12.0); 
    } 
} 

Ma quando cerco di test di unità (JUnit 4.10) questo:

public class MyTest { 
    @Named("Special-Fizz") private Fizz specialFizz; 

    @Test 
    public void usingNamedShouldInjectSpecialFizz() { 
     MyModule mod = new MyModule(); 
     Injector injector = Guice.createInjector(mod); 

     specialFizz = injector.getInstance(Fizz.class); 

     Assert.assertTrue(specialFizz != null); 
    } 
} 

Questo passa. Fin qui tutto bene. Ma poi se cambio il nome del campo specialFizz:

@Named("Special-Fuzz-This-Shouldnt-Work") private Fizz specialFizz; 

e ri-eseguire il test, passa ancora. Perché?!? Dove sto andando fuori strada qui? Grazie in anticipo.

risposta

3

Molto strano. Guice dovrebbe lamentarsi se non riesce a trovare un legame Named che sta iniettando. Sono un po 'confuso dal test, però. Non so cosa fa injector.inject. Intendi injectMembers? Potrebbe essere più sensato avere un'istanza del tuo POJO e assicurarsi che funzioni come ti aspetti. Forse qualcosa del tipo:

public class FizzTest { 

    public static class MyModule extends AbstractModule { 
    @Override 
    protected void configure() { 
    } 

    @Provides 
    @Singleton 
    @Named("Special-Fizz") 
    public Fizz providesFizz() { 
     return new Fizz(true); 
    } 
    } 

    public static class Fizz { 
    boolean special = false; 
    public Fizz() {} 
    public Fizz(boolean special) { 
     this.special = special; 
    } 
    } 

    public static class MyPOJO { 
    @Inject @Named("Special-Fizz") 
    private Fizz fizz; 

    @Inject 
    private Fizz otherFizz; 
    } 

    @Test 
    public void test() { 
    MyModule mod = new MyModule(); 
    Injector injector = Guice.createInjector(mod); 

    MyPOJO pojo = injector.getInstance(MyPOJO.class); 
    assertTrue(pojo.fizz.special); 
    assertTrue(!pojo.otherFizz.special); 
    } 

} 
+0

Grazie @condit (+1) - è stato un errore da parte mia nel digitare questa domanda. Ho modificato la mia domanda originale per mostrare che in realtà sto chiamando 'injector.getInstance', non' injector.inject'. Questo cambia qualcosa per te? 'GetInstance' non è corretto per me usare qui? Se è così, perché, e che cos'è? Grazie ancora! – IAmYourFaja

+0

Nel tuo test stai chiedendo all'iniettore un'istanza di 'Fizz' che sarà sempre in grado di fornirti (a causa del tuo metodo' @ Provides'). Penso che tu voglia ottenere un'istanza di 'MyPOJO' invece. Nota che il 'Fizz' che stai ricevendo non è correlato al membro' Fizz' del test. Quindi la modifica di '@ Named' non avrà alcun effetto in questo caso. – condit

+0

Lo hai inchiodato. Ho appena chiesto di iniettare un 'MyPOJO' e ha iniettato correttamente la sua proprietà' Fizz' con il mio fizz speciale. Mistero risolto: solo un metodo di test poco efficace. Grazie ancora! – IAmYourFaja

2

Guice vede il metodo @Provides e utilizza felicemente quello per iniettare il Fizz. Se si vuole avere un caso particolare di Fizz, è possibile eliminare le annotazioni dal metodo providesFizz() e invece legarsi con

bind(Fizz.class) 
    .annotatedWith(Names.named("Special-Fizz") 
    .toInstance(providesFizz()); 

In questo modo, si dice Guice esattamente quali Fizz da utilizzare come "Special-Fizz", pur continuando a farlo iniettare "normalmente" Fizz altrimenti.

Disclaimer: Non ho ancora provato un setup come il tuo, ma ne ho usato uno simile. Fammi sapere se funziona o no.

+0

Grazie a @Bradley T. Hughes (+1) - ** tuttavia ** il tuo suggerimento non cambia nulla. Il test unitario passa ancora, indipendentemente da ciò che tu chiami "Fizz". Hai menzionato qualcosa che pensavo fosse interessante. Hai detto "* In realtà non ho provato un setup come il tuo ... *", tuttavia, dalla tua risposta deduco che ti sembra abbastanza comodo usare Guice. Quindi mi chiedo: * È una configurazione bizzarra che sto usando? * Ho pensato che il * punto * di Guice fosse usare le Classi e le Annotazioni insieme per individuare esattamente quale tipo/config si desidera iniettare ... – IAmYourFaja

+0

.. .so sto facendo qualcosa qui che è fuori dall'ordinario? Se è così, perché?!? Dove sto fraintendendo il normale uso di Guice? Grazie ancora! – IAmYourFaja

+0

Non penso sia una configurazione bizzarra. E ad essere onesti, non ho usato Guice così tanto, quindi non sono certo un esperto.La differenza è che il codice su cui sto lavorando usa la stessa annotazione per iniettare due tipi diversi (una singola istanza di ciascuno). –

Problemi correlati