Как ввести 3 экземпляра одного типа с различной зависимостью от Guice?

Я использую Guice для управления своей классовой зависимостью. У меня есть класс LogicHandler, который зависит от нескольких классов компонентов.

  public interface LogicHandler {
      private Component component1;
      private Component component2;
      private Component component3;
  }

  public interface Component {
      public String doWork();
  }

У меня будет 3 экземпляра LoigcHanlder. Использование какого экземпляра будет решено во время выполнения. У каждого экземпляра будет своя реализация Компонента, и вся реализация предопределена.

Если бы я использовал Spring DI, конфигурация xml была бы похожа на:

<bean id="handler1" class="org.sample.handlers.DefaultHanlder">
  <property name="component1" ref="componentImplementationA" />
  <property name="component2" ref="componentImplementationB" />
  <property name="component3" ref="componentImplementationC" />
</bean>

<bean id="handler2" class="org.sample.handlers.DefaultHanlder">
  <property name="component1" ref="componentImplementationD" />
  <property name="component2" ref="componentImplementationE" />
  <property name="component3" ref="componentImplementationF" />
</bean>

<bean id="handler3" class="org.sample.handlers.DefaultHanlder">
  <property name="component1" ref="componentImplementationG" />
  <property name="component2" ref="componentImplementationH" />
  <property name="component3" ref="componentImplementationI" />
</bean>

Примечание: все обработчики реализованы в DefaultHanlder.

Использование экземпляра обработчика на основе некоторых параметров.

2 ответа

Решение

Предполагая, что я правильно понимаю ваш вопрос, вы хотели бы выбрать конкретную конкретную реализацию для привязки на основе определенного параметра. Один из способов сделать это - создать модуль, который принимает в качестве конструктора параметры, необходимые для принятия решения, какой модуль связывать. Логика привязки конкретной конкретной реализации будет заключаться в bind метод модуля. Например

public class YourModule extends AbstractModule {

Parameters settings;

public YourModule(Parameters settings) {
    this.settings = settings;
}

@Override
protected void configure() {
   if(settings.val == 1) {
      bind(DefaultHanlder.class).toInstance(ComponentA.class);
   } else if(settings.val == 2) {
      bind(DefaultHanlder.class).toInstance(ComponentB.class);
   }
   .
   .
   .
}

Когда вы создаете инжектор, используйте YourModule модуль так, чтобы правильная проводка была на месте. Затем инжектор должен ввести соответствующий конкретный класс для DefaultHanlder без вашего клиентского кода, зная, как правильно выбрать конкретную реализацию.

Возможно, есть и другие способы сделать это (например, AssistedInjection также может работать), но использовать отдельный модуль довольно просто.

Используйте квалификаторы (например, @Named("handler1")) и явно связывайте свои экземпляры.

 bind(Component.class).annotatedWith(Names.named("handler1").toInstance(...);
Другие вопросы по тегам