Как связать определенный параметр с экземпляром пользовательской аннотации? - PullRequest
0 голосов
/ 04 июля 2011

Как заставить работать следующую работу с помощью Guice?

// The Guice Module configuration
void configure() {
  // The following won't compile because HelpTopicId is abstract.
  // What do I do instead?
  bind(new TypeLiteral<String>(){}).
      annotatedWith(new HelpTopicId("A")).toInstance("1");
  bind(new TypeLiteral<String>(){}).
      annotatedWith(new HelpTopicId("B")).toInstance("2");
}

public @interface HelpTopicId {
  public String helpTopicName();
}

public class Foo {
  public Foo(@HelpTopicId("A") String helpTopicId) {
    // I expect 1 and not 2 here because the actual parameter to @HelpTopicId is "A"
    assertEquals(1, helpTopicId);
  }
}

Ответы [ 2 ]

1 голос
/ 04 июля 2011

Вероятно, самый простой способ сделать это - использовать @Provides методы:

@Provides @HelpTopicId("A")
protected String provideA() {
  return "1";
}

Кроме того, вы можете создать инстанцируемую реализацию аннотации / интерфейса HelpTopicId, аналогичную реализации Names.named (см. NamedImpl ). Имейте в виду, что существуют некоторые специальные правила для того, как такие вещи, как hashCode(), реализованы для аннотации ... NamedImpl следует этим правилам.

Кроме того, использование new TypeLiteral<String>(){} расточительно ... String.class можно использовать вместо него. Кроме того, для String, int и т. Д. Обычно следует использовать bindConstant() вместо bind(String.class). Это проще, требует, чтобы вы предоставили обязательную аннотацию, и ограничено примитивами, String s, Class литералами и enum s.

0 голосов
/ 04 июля 2011

Конструктор Foo(String) должен быть аннотирован @Inject.

Вместо того, чтобы использовать собственную аннотацию HelpTopicId, попробуйте использовать аннотацию Guice Named.

void configure() {
  bind(new TypeLiteral<String>(){}).annotatedWith(Names.named("A")).toInstance("1");
  bind(new TypeLiteral<String>(){}).annotatedWith(Names.named("B")).toInstance("2");
}

public class Foo {
  @Injected
  public Foo(@Named("A") String helpTopicId) {
    assertEquals("1", helpTopicId);
  }
}

Если вы хотите развернуть собственную реализацию интерфейса @Named, взгляните на реализацию Guice в пакете com.google.inject.name.

...