2009-06-15 6 views
21

Может быть, я просто слепой, но я не вижу, как использовать Guice (только начиная с ним), чтобы заменить new вызов в этом методе:Как использовать Google Guice для создания объектов, требующих параметров?

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

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

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

Как я мог бы это сделать с Guice (2.0)?

ответ

27

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

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

+7

Япом, AssistedInject является лучшим решением. http://code.google.com/p/google-guice/wiki/AssistedInject –

+1

Вот короткая публикация, о которой я писал. Assisted Injection - прекрасный инструмент для решения некоторых проблем, и я считаю, что это не так хорошо известно. Хорошая работа, распространяющая знания. http://ripper234.com/p/assisted-injection-in-guice/ – ripper234

+0

Где я могу получить .jar для помощи? Он недоступен для загрузки по адресу http://code.google.com/p/google-guice/downloads/list. –

2

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

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

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

Реализации Процессора предназначены для того, чтобы быть неизменными, создавая их один раз со всеми необходимыми данными, а затем запрашивать их только для работы. –

9

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

Они покрыты в Guice Docs here и here.

Поставщик будет выглядеть как

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); 
} 
+0

Большое спасибо, это, кажется, то, что я искал. Иногда вы не видите лес для всех деревьев. –

+0

И вы хотите связать DebugProcessorProvider с модулями отладки, но если вы используете Guice, вы, вероятно, уже поняли это. –

+1

Видя, как API теперь изменился на Process.isEnabled (anInputValue) (так же, как и в моем ответе), зачем беспокоиться о поставщике сейчас?Почему бы просто не иметь одного процессора и полностью пропустить Поставщик? – tddmonkey