2009-10-14 15 views
20

Jestem nowy w Guice i tutaj jest naiwne pytanie. Dowiedziałem się, że możemy powiązać ciąg do określonej wartości przez:Jak powiązać ciąg do zmiennej w Guice?

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

Ale co, jeśli chcę wiązać String do ewentualnych znaków?

Albo myślę, że może to być opisane w następujący sposób:

Jak mogę zastąpić "new SomeClass (String strParameter)" z Guice?

+2

DI (Injection Injection) z tymi wszystkimi trikami sprawia, że ​​czytanie kodu jest trudniejsze, utracił swój pierwotny cel. w większości przypadków NIE jest to zależne od wstrzyknięcia zależności, utrzymuj kontekst w jednym miejscu. Ułatwia to konserwację. –

Odpowiedz

37

Najpierw należy opisywanie konstruktora dla SomeClass:

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

wolę używać niestandardowych adnotacji, tak:

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

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

Następnie trzeba zapewnić wiążący w module :

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

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

Następnie, gdy Guice tworzy SomeClass, wprowadzi parametr. Na przykład, jeśli SomeOtherClass zależy SomeClass:

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

Często, kiedy myślisz, że chcesz wprowadzić ciąg znaków, chcesz wstrzyknąć obiekt. Na przykład, jeśli ciąg jest adresem URL, często wstrzykuję URI z adnotacją wiążącą.

To wszystko zakłada, że ​​istnieje pewna stała wartość, którą można zdefiniować w czasie tworzenia modułu dla ciągu. Jeśli wartość nie jest dostępna w czasie tworzenia modułu, możesz użyć AssistedInject.

+0

Dlaczego głosy na dół? – NamshubWriter

0

znajdę rozwiązanie w FAQ z Guice:

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

Oprócz definiowania adnotację i atrybut smyczkowy mymodule, muszę napisać poniżej linii, aby uzyskać instancję SomeClass:

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

Ale przypomniałem sobie, że Injector.getInstance() nie powinno być używane z wyjątkiem obiektu głównego, więc czy istnieje lepszy sposób na zrobienie tego?

18

Może to być nie na temat, ale Guice sprawia, że ​​konfiguracja jest znacznie łatwiejsza niż pisanie wyraźnego powiązania dla każdego potrzebnego ciągu. Można tylko mieć plik konfiguracyjny dla nich

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

i voilà całego config jest gotowy do wstrzyknięcia:

@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); 
} 

Teraz wystarczy utworzyć swój Java properties filemyconfig.properties u podstaw ścieżce klas z

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

lub połączyć informacje autoryzacyjne z innego źródła z właściwościami i gotowe.

Powiązane problemy