我很难弄清楚如何使用Guice将接口绑定到枚举。
public interface Snack {
public int caloriesCount();
}
public enum Chocolate implements Snack {
MILK(20),
DARK(5),
WHITE(10);
private int calCount;
private Chocolate(int calCount) {
this.calCount = calCount;
}
@Override
public int caloriesCount() {
return calCount;
}
}
如果我尝试:
bind(Snack.class).to(Chocolate.class);
我得到No implementation for Chocolate was bound
我理解我不应该尝试绑定到枚举,而应该绑定到枚举值的集合,但它无法实现如何实现。 感谢任何提示。 谢谢, Maciek
答案 0 :(得分:12)
绑定到类似的枚举类是不可能的,因为Guice无法创建自己的实例。在这里,默认行为是创建Chocolate
的新实例,这没有多大意义 - every possible instance of an enum must be declared at compile time within the enum itself,而且Guice不会为您挑选任意现有实例。
您可能希望改为执行以下三项操作之一:
将Snack
绑定到特定类型的Chocolate
。
bind(Snack.class).toInstance(Chocolate.DARK);
将Snack
绑定到Chocolate
,将Chocolate
绑定到特定类型的Chocolate
。这与上面类似,但现在您可以直接请求Chocolate
并获取实例,而不是只能请求Snack
。
bind(Snack.class).to(Chocolate.class);
bind(Chocolate.class).toInstance(Chocolate.DARK);
允许开发人员注入Set<Snack>
,这恰好会返回所有Chocolate
个实例。
// manual wildcard required so we don't get an ImmutableSet<Chocolate>
Set<Snack> setOfSnacks = ImmutableSet.<Snack>copyOf(Chocolate.values());
// bind a Set<Snack> specifically
bind(new TypeLiteral<Set<Snack>>() {}).toInstance(setOfSnacks);
您可以使用任何Set实现,但由于所有toInstance
绑定都是隐式单例,因此如果您使用Guava's ImmutableSet
或至少Collections.unmodifiableSet
,则可以降低一些修改风险。如果这接近您想要的,您可能有兴趣了解可选的Multibindings plugin。
当然,您也可以编写自己的Provider<Set<Snack>>
或@Provides Set<Snack>
方法,从而每次都获得一个新的设置实例...但如果您希望在应用中使用此实例,则可能会分享一个不可变副本更有意义。