java - 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 FrenchSpellChecker implements IsSpellChecker {....}
public class EnglishSpellChecker implements IsSpellChecker {....}
@BindingAnnotation public @interface English {}
@BindingAnnotation public @interface French {} 

然后在我的模块中,我将接口(interface)绑定(bind)到它们各自的实现,并使用相应的绑定(bind)注释来注释拼写检查器。

现在,假设我需要基于运行时变量构建一个使用英语或法语拼写检查器的电子邮件程序。

我考虑在我的模块中使用命名提供程序:

@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 提供的任何服务中,您最好的选择是要求注入(inject) Provider<IsEmailer> ,或者@English Provider<IsEmailer>@French Provider<IsEmailer> 。 Guice 不会真正创建元素,直到您调用 get关于Provider ,因此创建 Provider 的开销非常非常轻。

  • 您不必绑定(bind)到提供程序即可获取提供程序。 Guice 将解析 X 的任何绑定(bind), Provider<X> ,或@Provides X任何注入(inject) XProvider<X>自动且透明。

  • Provider实现可以采用注入(inject)的参数,就像 @Provides 一样。方法。

  • 如果你想绑定(bind)很多东西到 @English@French ,您也可以调查private modules ,因为这听起来像 "robot legs"对我来说是个问题。

最简单的方法就是使用第一个项目符号并注入(inject) Provider每个,特别是如果您只这样做一次。

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

@Provides IsEmailer provideEmailer(Settings settings,
    @English Provider<IsEmailer> englishEmailer,
    @French Provider<IsEmailer> frenchEmailer) {
  if (settings.isEnglish()) {
    return englishEmailer.get();
  } else {
    return frenchEmailer.get();
  }
}

关于java - GUICE - 在运行时决定对象图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15214795/

相关文章:

java - 使用Jenkins和Gradle运行Flyway迁移-无法解析位置classpath:db/migration

angularjs - 如何注入(inject)模块并使其可供应用程序的所有模块和子模块访问(出现未知提供者错误)

java - Guice:在没有 @Singleton 或以其他方式修改实现的情况下配置单例

java - Jar 文件中的 Guice 和 Reflections

node.js - 在 node js 中构建可扩展的 tcp 服务器

java - 有没有办法检查我是否在 Guice 的 servlet 请求中?

java - 运行 paint 方法时的默认颜色是什么

java - 定义自己的XMLEventReader来实现Closeable接口(interface)

java - 如何从 java 中使用 Crossover 启动命令行应用程序?

java - 如何加载两个ResourceBundle并分别注入(inject)