2009-10-14 1 views
20

Я новичок в Guice, и вот наивный вопрос. Я узнал, что мы могли бы связать строки с определенным значением через:Как связать строку с переменной в Guice?

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

Но что, если я хочу, чтобы связать строку любых возможных символов?

Или я думаю, что это может быть описано следующим образом:

Как я могу заменить "новый SomeClass (String strParameter)" с Guice?

+2

DI (зависимая инъекция) со всеми этими трюками делает код чтения более сложным, потерял исходную цель. в большинстве случаев гораздо проще использовать НЕ-зависимую инъекцию, поддерживать контекст в одном месте. Это упрощает обслуживание. – 2013-08-14 23:19:43

ответ

37

Сначала необходимо аннотировать конструктор SomeClass:

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

Я предпочитаю использовать пользовательские аннотации, например:

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

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

Тогда вам необходимо обеспечить привязку в вашем модуле :

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

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

Затем время Guice создает SomeClass, оно будет вводить параметр. Например, если SomeOtherClass зависит от SomeClass:

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

Часто, когда вы думаете, что вы хотите, чтобы ввести строку, вы хотите, чтобы ввести объект. Например, если String является URL-адресом, я часто вставляю URI с обязательной аннотацией.

Все это предполагает, что существует некоторое постоянное значение, которое вы можете определить во время создания модуля для String. Если значение не доступно во время создания модуля, вы можете использовать AssistedInject.

+0

Почему пустые голоса? – NamshubWriter

0

я найти решение в FAQ по Guice:

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

Кроме того, чтобы определить аннотацию и атрибут String, в MyModule, мне нужно написать ниже линии, чтобы получить экземпляр SomeClass:

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

Но я помню, что Injector.getInstance() не следует использовать, кроме корневого объекта, так есть ли лучший способ сделать это?

18

Это может быть не по теме, но Guice упрощает настройку, чем писать явное привязку для каждой строки, в которой вы нуждаетесь. Вы можете просто иметь конфигурационный файл для них:

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

и вуаля все ваши конфигурации готова для инъекций:

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

Теперь просто создать свой Java properties filemyconfig.properties в корне вашего пути к классам с

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

или слить информацию авторизации из другого источника в свойства, и вы настроены.