Как использовать Google Guice для создания объектов, которые требуют параметров? - PullRequest
21 голосов
/ 15 июня 2009

Может быть, я просто слепой, но я не понимаю, как использовать Guice (только начиная с него) для замены вызова new в этом методе:

public boolean myMethod(String anInputValue) {
    Processor proc = new ProcessorImpl(anInputValue);
    return proc.isEnabled();
}

Для тестирования может существовать другая реализация Процессора, поэтому я бы хотел избежать вызова new и в ходе этого избавиться от зависимости от реализации.

Если бы мой класс мог просто запомнить экземпляр Processor, я мог бы внедрить его через конструктор, но, поскольку процессоры разработаны так, чтобы быть неизменяемыми, мне каждый раз нужен новый.

Как мне поступить и достичь этого с Guice (2.0)?

Ответы [ 3 ]

27 голосов
/ 15 июня 2009

Прошло некоторое время с тех пор, как я использовал Guice, но я помню то, что называется «вспомогательная инъекция». Это позволяет вам определить фабричный метод, где некоторые параметры поставляются, а некоторые вводятся. Вместо внедрения процессора вы вводите фабрику процессоров, у которой есть метод фабрики, который принимает параметр anInputValue.

Я указываю вам на Javadoc FactoryProvider . Я считаю, что это должно быть полезно для вас.

10 голосов
/ 15 июня 2009

Вы можете получить желаемый эффект, введя «Провайдера», который можно попросить во время выполнения дать вам Процессор. Поставщики предоставляют способ отложить построение объекта до момента запроса.

Они включены в Guice Docs здесь и здесь .

Провайдер будет выглядеть примерно так

public class ProcessorProvider implements Provider<Processor> {
    public Processor get() {
        // construct and return a Processor
    }
}

Поскольку провайдеры создаются и внедряются Guice, им самим могут вводиться биты.

Ваш код будет выглядеть примерно так:

@Inject
public MyClass(ProcessorProvider processorProvider) {
    this.processorProvider = processorProvider;
}

public boolean myMethod(String anInputValue) {
    return processorProvider.get().isEnabled(anInputValue);
}
2 голосов
/ 15 июня 2009

Требуется ли вашему процессору доступ к anInputValue на протяжении всего его жизненного цикла? Если нет, может ли значение быть передано для вызова метода, который вы используете, что-то вроде:

@Inject
public MyClass(Processor processor) {
    this.processor = processor;
}

public boolean myMethod(String anInputValue) {
    return processor.isEnabled(anInputValue);
}
...