Ответ 1
Способ обмана: Придерживайтесь input
в статической переменной или singleton ThreadLocal
. Установите его перед запуском вашего конвейера и очистите его после его завершения. Свяжите все остальное через DI.
Необычный способ: В A
, обратитесь к @PipelineInput String inputString
, но не привязывайте его к основному инжектору. В противном случае свяжите зависимости, как обычно, в том числе со ссылкой на @PipelineInput
в других классах, связанных с конвейером. Когда вам понадобится D
, получите его из вашей реализации DFactory
, которую я вызываю PipelineRunner
.
public class PipelineRunner {
@Inject Injector injector; // rarely a good idea, but necessary here
public D createD(final String inputForA) {
Module module = new AbstractModule() {
@Override public void configure() {
bindConstant(inputForA).annotatedWith(PipelineInput.class);
}
};
return injector.createChildInjector(new PipelineModule(), module)
.getInstance(D.class);
}
}
Естественно, что попытки привязки для A
, B
, C
и D
выходят за пределы PipelineRunner
из-за отсутствия @PipelineInput String
- вы получите CreationException
, когда вы создайте инжектор с этими неудовлетворенными зависимостями, как вы обнаружили, но эти зависимости на основе трубопроводов должны быть легко разделены на модуль, который вы устанавливаете в дочерний инжектор.
Если это слишком хаки, помните, что PrivateModules также ", реализованный с использованием родительских инжекторов", и что весь смысл инъекции зависимостей сделать зависимость, подобную inputForA
доступной для всего графика объекта развязанным способом.