2009-10-14 12 views
20

Sono nuovo di Guice e qui c'è una domanda ingenua. Ho imparato che potremmo legare stringa in un valore particolare attraverso:Come associare String a variabile in Guice?

bind(String.class) 
     .annotatedWith(Names.named("JDBC URL")) 
     .toInstance("jdbc:mysql://localhost/pizza"); 

Ma cosa succede se voglio legare String ad eventuali personaggi?

O penso che potrebbe essere descritto in questo modo:

Come faccio a sostituire "nuovo SomeClass (String strParameter)" con Guice?

+2

DI (dipendenza Injection) con tutti questi trucchi rende più difficile la lettura del codice, ha perso il suo obiettivo di origine. è molto più facile iniettare la dipendenza nella maggior parte dei casi, mantenere il contesto in un unico posto. Questo rende la manutenzione molto più semplice. –

risposta

37

Innanzitutto è necessario annotare il costruttore per SomeClass:

class SomeClass { 
    @Inject 
    SomeClass(@Named("JDBC URL") String jdbcUrl) { 
    this.jdbcUrl = jdbcUrl; 
    } 
} 

Io preferisco usare le annotazioni personalizzate, in questo modo:

class SomeClass { 
    @Inject 
    SomeClass(@JdbcUrl String jdbcUrl) { 
    this.jdbcUrl = jdbcUrl; 
    } 

    @Retention(RetentionPolicy.RUNTIME) 
    @Target({ElementType.FIELD, ElementType.PARAMETER}) 
    @BindingAnnotation 
    public @interface JdbcUrl {} 
} 

allora avete bisogno di fornire un legame nel vostro modulo :

public class SomeModule extends AbstractModule { 
    private final String jdbcUrl; // set in constructor 

    protected void configure() { 
    bindConstant().annotatedWith(SomeClass.JdbcUrl.class).to(jdbcUrl); 
    } 
} 

Quindi, una volta che Guice crea SomeClass, inserisce il parametro. Per esempio, se SomeOtherClass dipende SomeClass:

class SomeOtherClass { 
    @Inject 
    SomeOtherClass(SomeClass someClass) { 
    this.someClass = someClass; 
    } 

Spesso, quando si pensa che si desidera iniettare una stringa, si vuole iniettare un oggetto. Ad esempio, se la stringa è un URL, inserisco spesso uno URI con un'annotazione vincolante.

Questo presuppone che esista un valore costante che è possibile definire durante la creazione del modulo per la stringa. Se il valore non è disponibile al momento della creazione del modulo, è possibile utilizzare AssistedInject.

+0

Perché i voti negativi? – NamshubWriter

0

trovo una soluzione nelle FAQ di Guice:

http://code.google.com/docreader/#p=google-guice&s=google-guice&t=FrequentlyAskedQuestions

Oltre a definire un'annotazione e un attributo stringa in MyModule, ho bisogno di scrivere sotto la linea per ottenere un'istanza di SomeClass:

SomeClass instance = Guice.createInjector(new MyModule("any string i like to use")).getInstance(SomeClass.class); 

Ma mi sono ricordato che Injector.getInstance() non dovrebbe essere usato tranne per l'oggetto radice, quindi c'è un modo migliore per farlo?

18

Questo potrebbe essere off-topic, ma Guice rende la configurazione molto più semplice rispetto alla scrittura di un'associazione esplicita per ogni stringa necessaria. Si può solo avere un file di configurazione per loro:

Properties configProps = Properties.load(getClass().getClassLoader().getResourceAsStream("myconfig.properties"); 
Names.bindProperties(binder(), configProps); 

e voilà tutta la vostra configurazione è pronto per l'iniezione:

@Provides // use this to have nice creation methods in modules 
public Connection getDBConnection(@Named("dbConnection") String connectionStr, 
            @Named("dbUser") String user, 
            @Named("dbPw") String pw,) { 
    return DriverManager.getConnection(connectionStr, user, pw); 
} 

Ora basta creare il Java properties filemyconfig.properties alla radice del classpath con

dbConnection = jdbc:mysql://localhost/test 
dbUser = username 
dbPw = password 

oppure unisci le informazioni di autorizzazione da un'altra fonte nelle proprietà e sei impostato.

Problemi correlati