2011-07-04 37 views
0

如何使用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

可能做到这一点最简单的方法是使用@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

构造函数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接口,一起来看看在吉斯在包com.google.inject.name实施。

+0

所有有效的点...仍然,'configure()'中的代码不会被编译。 – ripper234

+0

我刚刚尝试过,'configure()'覆盖的方法正在编译。编译器给出的信息是什么? –

+0

啊,对不起,我太快了,为了我自己的利益。我特别询问了自定义注释,而不是命名注释(我熟悉这些注释)。 – ripper234