Пример Guice о том, как правильно связать объекты - PullRequest
0 голосов
/ 16 февраля 2012

Я пытаюсь выучить Guice, и у меня есть вопрос о том, как правильно соединить вещи.Я пытаюсь получить вызов в методе BoofPanels doSomething () для автоматического использования MockFooImpl, но я не думаю, что все правильно подключено.

В моем случае у меня есть:

@ImplementedBy(MockFooImpl.class)
public interface FooInterface {
    public int getBar(String one, String two);
}


@Singleton
public final class MockFooImpl implements FooInterface {
    @Inject
    public MockFooImpl() {
    }

    @Override
    public int getBar(String one, String two) {
      return 1;
    }
}


public class Baz extends JFrame  {

   private BoofPanel boofPanel;

   public Baz(String one, String two, Injector injector){
        // Constructor with args
        boofPanel = new BoofPanel("aString", 565);
        injector.injectMembers(boofPanel);
   }

   public static void main(String[] args){
       final Injector injector = Guice.createInjector();

       java.awt.EventQueue.invokeLater(new Runnable() {  
           @Override
           public void run() {
               final Baz baz = new Baz("one","two", injector);
               baz.setVisible(true);
           }
       });
   }
}


public class BoofPanel extends JPanel {
    @Inject
    private FooInterface fooI;

    public BoofPanel(String aString, int anInt){

    }
    public void doSomething(){
       fooI.getBar();
    }
}

Любая помощь будет оценена.

Спасибо!

Ответы [ 2 ]

2 голосов
/ 16 февраля 2012

Guice не волшебство. Он будет внедряться в объект, только если он его создаст или вы попросите об этом. Если вы создаете свою собственную BoofPanel, вам нужно будет попросить Guice внедрить ее. Добавьте конструктор в Baz, который выглядит следующим образом:

public Baz(Injector injector) {
    boofPanel = new BoofPanel(whatever, the, params, are);
    injector.injectMembers(boofPanel);
}

Конструктор BoofPanel не должен ничего делать с переменной fooI; это может оставить это нулевым. Вам также нужно будет сделать переменную инжектора main окончательной, чтобы анонимный класс, созданный в main, мог перехватить ее и передать в конструктор Baz.

Если вы предпочли бы, чтобы BoofPanel был создан Guice, вам нужно будет предоставить все необходимые параметры конструктора для Guice и вызвать injectMembers на самом Baz.

РЕДАКТИРОВАТЬ : конкретные изменения в коде выше, после редактирования.

  1. Добавьте final к этому объявлению, чтобы сделать его пригодным для использования внутри анонимного внутреннего класса:

    final Injector injector = Guice.createInjector();

  2. Удалите эту строку, так как она не нужна:

    injector.getInstance(MockFooImpl.class);

  3. Добавьте инжектор к вызову конструктора Baz, чтобы получить его там, где создается BoofPanel (я также удалил ненужные final здесь):

    Baz baz = new Baz("one", "two", injector);

  4. Добавьте инжектор в объявление конструктора Baz, чтобы получить его из основного метода:

    public Baz(String one, String two, Injector injector) {

  5. Добавьте инъекцию в boofPanel в конструктор Baz, сразу после строки new BoofPanel, чтобы Guice ввел BoofPanel:

    injector.injectMembers(boofPanel);

Вот и все.

1 голос
/ 16 февраля 2012

Вы, вероятно, хотите

public class BoofPanel extends JPanel {
  private FooInterface fooI;
  @Inject BoofPanel(FooInterface foo) {
     this.fooI = foo;
  }
  public void doSomething() {
    fooI.getBar();
  }
}

, а затем в своей основной области вы, вероятно, захотите что-то вроде injector.createInstance(BoofPanel.class), и оно автоматически выполнит требование FooInterface с MockFooImpl.

...