2013-06-07 22 views
5

ho il seguente codice utilizzando le associazioni Guice:Guice: Legatura diversi oggetti con diverse dipendenze

public class MyApplication { 
    public static void main(String[] args) { 
     Guice.createInjector(new AbstractModule() { 
      @Override 
      protected void configure() { 
       bind(Foo.class).annotatedWith(Names.named("first")).toInstance(new Foo("firstFoo")); 
       bind(Foo.class).annotatedWith(Names.named("second")).toInstance(new Foo("secondFoo")); 

       bind(Bar.class).to(BarImpl.class); 

       bind(MyApplication.class).asEagerSingleton(); 
      } 
     }); 
    } 

    private @Named("first") Bar first; 
    private @Named("second") Bar second; 

    static @Value class Foo { String name; } 
    static interface Bar {} 

    static class BarImpl implements Bar { 
     @Inject @Named Foo foo; 
    } 
} 

Sto cercando di ottenere un oggetto Bar per entrambi denominati Foo s iniettati nella mia applicazione. Fondamentalmente, dovrebbe in qualche modo collegare lo a Foo con quello su Bar. Ho provato diverse soluzioni, dal mettere @Named su tutto per scrivere una personalizzata Provider. Quest'ultimo non ha funzionato perché non ho accesso al valore dell'annotazione @Named all'interno del provider. Penso che la soluzione sia da qualche parte nella riga bind(Bar.class).to(BarImpl.class);, dicendogli di ricordare il valore dell'annotazione @Named.

La mia domanda è, è possibile, e se sì, come?

risposta

10

Si sta utilizzando PrivateModules. Fondamentalmente:

Le informazioni di configurazione di un modulo privato sono nascoste dall'ambiente per impostazione predefinita. Solo i collegamenti esplicitamente esposti saranno disponibili per gli altri moduli e per gli utenti dell'iniettore. Per ulteriori spiegazioni, vedere this FAQ entry.

Ecco come si sarebbe usarlo:

protected void configure() { 
    install(new PrivateModule() { 
     @Override 
     protected void configure() { 
      // #bind makes bindings internal to this module unlike using AbstractModule 
      // this binding only applies to bindings inside this module 
      bind(Foo.class).toInstance(new Foo("first")); 
      // Bar's foo dependency will use the preceding binding 
      bind(Bar.class).annotatedWith(Names.named("first")).to(BarImpl.class); 
      // if we'd stop here, this would be useless 
      // but the key method here is #expose 
      // it makes a binding visible outside as if we did AbstractModule#bind 
      // but the binding that is exposed can use "private" bindings 
      // in addition to the inherited bindings    
      expose(Bar.class).annotatedWith(Names.named("first")); 
     } 
    }); 
    install(new PrivateModule() { 
     @Override 
     protected void configure() { 
      bind(Foo.class).toInstance(new Foo("second")); 
      bind(Bar.class).annotatedWith(Names.named("second")).to(BarImpl.class); 
      expose(Bar.class).annotatedWith(Names.named("second")); 
     } 
    }); 
     bind(MyApplication.class).asEagerSingleton(); 
    } 
} 

Ora avete efficacemente 2 Bar ciascuno dei quali assomigliano

static class BarImpl implements Bar { 
    @Inject Foo foo; 
} 

ma con la potenza di PrivateModules avere un'implementazione diversa diretto a la stessa dipendenza

Spero che abbia senso.

+0

Grazie, sembra promettente. Ci proverò lunedì. – Jorn

+1

Sì, questo ha risolto il mio problema. Grazie ancora! – Jorn

+0

Prego! –

Problemi correlati