How do I bind a specific parameter to an instance of a custom annotation?

喜你入骨 提交于 2019-12-11 15:19:32

问题


How do I make the following work using 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);
  }
}

回答1:


Probably the simplest way to do this would be to use @Provides methods:

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

Alternatively, you could create an instantiable implementation of the HelpTopicId annotation/interface similar to the implementation of Names.named (see NamedImpl). Be aware that there are some special rules for how things like hashCode() are implemented for an annotation... NamedImpl follows those rules.

Also, using new TypeLiteral<String>(){} is wasteful... String.class could be used in its place. Furthermore, for String, int, etc. you should typically use bindConstant() instead of bind(String.class). It's simpler, requires that you provide a binding annotation, and is limited to primitives, Strings, Class literals and enums.




回答2:


Constructor Foo(String) has to be annotated with @Inject.

Instead of using your own HelpTopicId annotation, you should try with Guice Named annotation.

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);
  }
}

If you want to roll out your own implementation of @Named interface, take a look at the Guice's implementation in the package com.google.inject.name.



来源:https://stackoverflow.com/questions/6571680/how-do-i-bind-a-specific-parameter-to-an-instance-of-a-custom-annotation

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!