dependency-injection - Dagger:注入(inject)@Named 字符串?

标签 dependency-injection dagger

编辑 2018-02-08:演示如何在 https://github.com/ravn/dagger2-named-string-inject-example 上执行此操作的示例项目- 注:the whole source is in a single file !

我正在研究 dagger 是否可以代替我们的 guice(因为我们的部署 Java 平台很慢)。

我在运行时构造了一个配置字符串映射,我希望根据需要注入(inject) dagger。

例如。如果我有

java.util.Map<String, String> map = new java.util.TreeMap<String, String>();
map.put("key", "value");


@Inject
Thermosiphon(Heater heater, @Named("key") String value) {
    this.heater = heater;
    System.out.println("value =" + value);
}

我想在值(value)中注入(inject)“值(value)”。

源代码中的示例没有任何 @Named 用法。只是尝试给出以下异常:
Exception in thread "main" java.lang.IllegalStateException: Errors creating object graph:
  No binding for @javax.inject.Named(value=key)/java.lang.String required by class bar.Thermosiphon
    at dagger.internal.ThrowingErrorHandler.handleErrors(ThrowingErrorHandler.java:34)
    at dagger.internal.Linker.linkRequested(Linker.java:146)
    at dagger.ObjectGraph$DaggerObjectGraph.getInjectableTypeBinding(ObjectGraph.java:288)
    at dagger.ObjectGraph$DaggerObjectGraph.get(ObjectGraph.java:249)
    at app.CoffeeApp.main(CoffeeApp.java:20)

我应该如何处理这个?

最佳答案

听起来您有一个 Map 并且您想使用将它们自动绑定(bind)到命名字符串的东西。你不能像在 Guice 中那样在 Dagger 中自动执行此操作,因为在 Guice 中你可以创建属性绑定(bind)器。
Dagger 需要在编译时了解所有绑定(bind),以便进行分析以确保满足所有绑定(bind)和依赖项
也就是说,你可以做这样的事情——它更像是样板,但它是合法的。

@Module(library = true)
public class PropertiesModule {
  public final Properties props;

  PropertiesModule(Properties props) {
    this.props = props;
  }

  @Provides @Named("property.one") String providePropertyOne() {
    props.getProperty("property.one", "some default");
  }

  @Provides @Named("property.two") String providePropertyTwo() {
    props.getProperty("property.two", "some other default");
  }
  ...
}
这将允许创建您需要的所有绑定(bind),但要从运行时值中满足。但是,键在编译时是已知的(并且必须是,因为无论如何您都在代码中使用 @Named("string literal") 。哎呀,如果您已将属性名称和默认值定义为常量字符串,您甚至可以做:
  @Provides @Named(PROPERTY_NAME_CONSTANT) String a() {
    props.getProperty(PROPERTY_NAME_CONSTANT, PROPERTY_NAME_CONSTANT_DEFAULT);
  }
它是更多的样板,但 Dagger 在试图消除大量样板的同时,更喜欢编译时分析而不是绝对样板减少。也就是说,我将提出一个可以改善这种情况的功能,即从已知列表或类似列表中为系统属性自动生成一个模块。我认为即使是这个样板也可以减少。

关于dependency-injection - Dagger:注入(inject)@Named 字符串?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18099909/

相关文章:

android - Dagger 2 注入(inject)后返回null

angularjs - 使用 karma 在 angular2 中运行测试时失败 : No provider for Reflector! 错误

android - Dagger 2 不生成组件

android - 如何为父 fragment 和子 fragment 提供相同的 ViewModel 实例

Android Dagger 并在任意时刻设置模块

java - 找不到MoreTypes类

c# - Transient 注入(inject) Singleton 有什么问题?

java - 使用运行时数据的依赖注入(inject) : Factories and direct dependencies

javascript - AngularJS - 在一个简单的应用程序上获取 "Uncaught Error: [$injector:modulerr]"消息

java - Dagger 2 : avoid exporting private dependencies