Guice,绑定到枚举

时间:2013-10-31 01:53:34

标签: java enums guice

我很难弄清楚如何使用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

1 个答案:

答案 0 :(得分:12)

绑定到类似的枚举类是不可能的,因为Guice无法创建自己的实例。在这里,默认行为是创建Chocolate的新实例,这没有多大意义 - every possible instance of an enum must be declared at compile time within the enum itself,而且Guice不会为您挑选任意现有实例。

您可能希望改为执行以下三项操作之一:

  1. Snack绑定到特定类型的Chocolate

    bind(Snack.class).toInstance(Chocolate.DARK);
    
  2. Snack绑定到Chocolate,将Chocolate绑定到特定类型的Chocolate。这与上面类似,但现在您可以直接请求Chocolate并获取实例,而不是只能请求Snack

    bind(Snack.class).to(Chocolate.class);
    bind(Chocolate.class).toInstance(Chocolate.DARK);
    
  3. 允许开发人员注入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>方法,从而每次都获得一个新的设置实例...但如果您希望在应用中使用此实例,则可能会分享一个不可变副本更有意义。