Java GUICE-在运行时决定对象图

Java GUICE-在运行时决定对象图,java,dependency-injection,guice,Java,Dependency Injection,Guice,我在复习Guice。假设我有以下设置: public interface IsEmailer {...} public interface IsSpellChecker {...} public class Emailer implements IsEmailer { @Inject public class Emailer(final IsSpellChecker spellChecker).... } public class FrenchSpellChecke

我在复习Guice。假设我有以下设置:

public interface IsEmailer {...}
public interface IsSpellChecker {...}
public class Emailer implements IsEmailer { 
       @Inject
       public class Emailer(final IsSpellChecker spellChecker)....
}
public class FrenchSpellChecker implements IsSpellChecker {....}
public class EnglishSpellChecker implements IsSpellChecker {....}
@BindingAnnotation public @interface English {}
@BindingAnnotation public @interface French {} 
然后在我的模块中,我将接口绑定到它们各自的实现,并用各自的绑定注释对拼写检查器进行注释

现在,假设基于一个运行时变量,我需要构造一个使用英语或法语拼写检查器的emailer

我想在我的模块中使用命名的提供者:

@Provides
@English
IsEmailer provideEnglishEmailer() {
    return new Emailer(new EnglishSpellChecker());
}

@Provides
@French
IsEmailer provideFrenchEmailer() {
    return new Emailer(new FrenchSpellChecker());
}
其工作原理如下:

IsEmailer emailer = myModule.getInstance(Key.get(IsEmailer.class,
                French.class));
这是做这种事情最干净的方式吗?毕竟,我被迫手工构造对象(在提供者中)

谢谢

首先请注意:

  • 通常,您希望尽可能避免使用
    getInstance
    ,但“根”元素除外(例如
    YourApplication
    )。在Guice提供的任何服务中,您最好的选择是要求注入
    提供者
    ,或者可能是
    @英语提供者
    @法语提供者
    。在调用
    提供程序
    上的
    get
    之前,Guice实际上不会创建元素,因此创建
    提供程序
    的开销非常小

  • 您不必绑定到提供程序就可以获得提供程序。Guice将自动且透明地解决
    X
    提供者
    @提供X
    的任何绑定,以注入
    X
    提供者

  • 提供程序
    实现可以采用注入参数,正如
    @提供的方法一样

  • 如果你想把很多东西绑定到
    @English
    @French
    ,你也可以进行调查,因为这听起来像是我的问题

最简单的方法就是使用第一个项目符号,并为每个项目注入一个
提供者
,特别是如果您只做了一次

如果您的运行时变量可以通过Guice访问,则还可以将其绑定到模块中。将其与上面提供的注释一起放入模块中。(如前所述,您可能需要重写它们,以分别接受
英语拼写检查器
法语拼写检查器
作为参数,以使拼写检查器能够注入它们自己的依赖项。)

@提供IsEmailer提供电子邮件程序(设置、,
@英语供应商,
@法国供应商(frenchEmailer){
if(settings.isEnglish()){
return englishEmailer.get();
}否则{
return frenchEmailer.get();
}
}

您可以使用一个。这将允许您插入
映射
,然后在运行时检索相应的拼写检查器。

从源代码中很好地描述了guice指南。我也学到了一些新东西!
@Provides IsEmailer provideEmailer(Settings settings,
    @English Provider<IsEmailer> englishEmailer,
    @French Provider<IsEmailer> frenchEmailer) {
  if (settings.isEnglish()) {
    return englishEmailer.get();
  } else {
    return frenchEmailer.get();
  }
}