How do I bind a specific parameter to an instance of a custom annotation?
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);
}
}
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, String
s, Class
literals and enum
s.
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
.
精彩评论