Внедрение метода Guice с использованием аннотаций - PullRequest
1 голос
/ 07 декабря 2011

У меня есть два Runnable класса, и я хочу внедрить зависимость между ними, чтобы SecondProcedure выполнялся с использованием Table, созданного FirstProcedure.

class FirstProcedure implements Runnable {
    private Table composers = new Table();

    public void run() {
        // populates the composers table
    }

    public Table getComposers() {
        return composers;
    }
}


class SecondProcedure implements Runnable {
    private Table composers;

    public void run() {
        // writes the name of each composer to the console
    }

    public Table setComposers(final Table composers) {
        this.composers = composers;
    }
}

.Идея состоит в том, что в моем основном классе я могу создать экземпляр обеих процедур, ввести соответствующую таблицу (которая должна правильно ссылаться, даже если она не будет заполнена этой точкой), определить зависимости между двумя процедурами, а затем запустить ихв правильном порядке.то есть будет уникальный экземпляр каждой из этих двух процедур (но я намеренно избегаю паттерна Singleton (анти), чтобы иметь возможность проводить правильные юнит-тесты).

Как я могу сделать это с помощью Guice?Могу ли я аннотировать метод setComposers чем-то вроде:

@InjectTable(procedure=FirstProcedure.class, name="composers")
public Table setComposers(final Table composers) {
    this.composers = composers;
}

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

Я не вижу ничего, что бы в полной мере соответствовало этой парадигме в AbstractModule методах *1019*.

(Кроме этого, я не слишком заинтересован в дизайне этой аннотациисам, с именем поля в строке, вместо того, чтобы явно как-то ссылаться на метод.)

1 Ответ

0 голосов
/ 02 февраля 2012

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

Похоже, что SecondProcedure имеет простую зависимость от Table:

class SecondProcedure {
  @Inject
  SecondProcedure(Table table) {
    this.table = table;
  } 
}

И FirstProcedure является провайдером таблицы:

class FirstProcedure implements Provider<Table> {
  public Table get() {
    return buildTheTable();
  }
}

Тогда вашему модулю просто нужно связать провайдера:

class SomeModule extends AbstractModule {
  protected void configure() {
    bind(Table.class).toProvider(FirstProcedure.class);
  }
}

Привязка JIT аннотированного конструктора @Inject обеспечит SecondProcedure, поэтому вам не нужно связывать его явно.

Как только вы это сделаете, вы можете подумать об изменении имени FirstProcedure на TableProvider.

Чтобы использовать FirstProcedure, вы просто вводите его или получаете из инжектора:

injector.getInstance(FirstProcedure.class).run();

Кроме того, синглтон-шаблон Гисе (область действия @Singleton) не является анти-паттерном, поскольку он ограничен инжектором.Существует множество случаев, когда это уместно, и одноэлементная реализация Guice не мешает тестированию.

Возможно, вас должно беспокоить статическое состояние.Сам Guice дает хорошее объяснение того, почему это плохо: http://code.google.com/p/google-guice/wiki/AvoidStaticState

...