Dagger:注入@Named 字符串? [英] Dagger: Inject @Named strings?

查看:19
本文介绍了Dagger:注入@Named 字符串?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

编辑 2018-02-08:示例项目演示了如何在 https://github.com/ravn/dagger2-named-string-inject-example - 注意:整个源代码在一个文件中

EDIT 2018-02-08: Sample project demonstrating how to do this at https://github.com/ravn/dagger2-named-string-inject-example - Note: the whole source is in a single file!

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

I am looking at whether dagger can replace guice for us (as our deployment Java platform is slow).

我在运行时构建了一个配置字符串映射,我希望根据需要注入 dagger.

I construct a map of configuration strings at runtime, which I would like to have dagger inject as needed.

例如如果我有

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);
}

我想在价值中注入价值".

I would like to have "value" injected in value.

源代码中的示例没有任何@Named 用法.只是尝试给出以下异常:

The examples in the source code does not have any @Named usages. Just trying gives the following exception:

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)

我应该如何处理这个问题?

How should I approach this?

推荐答案

听起来你有一个 Map并且您想使用将这些自动绑定到命名字符串的东西.在 Dagger 中您无法像在 Guice 中那样自动执行此操作,因为在 Guice 中您可以创建一个属性绑定器.

It sounds like you have a Map<String, String> and you want to use something that binds these automatically to named strings. You cannot do that as automatically in Dagger as you can in Guice, since in Guice you can create a properties binder.

Dagger 需要在编译时了解所有绑定,以便进行分析以确保满足所有绑定和依赖项

Dagger requires knowledge of all of your bindings at compile-time, in order to do the analysis to ensure that all bindings and dependencies are satisfied

也就是说,你可以做这样的事情 - 它更像样板,但它是合法的.

That said, you could do something like this - it is more boiler plate, but it is legit.

@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");
  }
  ...
}

这将允许您需要创建的所有绑定,但要满足运行时值.但是,键在编译时是已知的(并且必须是,因为无论如何您都在代码中使用 @Named(string literal").哎呀,如果您已将属性名称和默认值定义为常量字符串,则可以甚至做:

This will allow for all of the bindings you need to be created, but to be satisfied from runtime values. The keys, however, are known at compile time (and must be, since you're using @Named("string literal") in your code anyway. Heck, if you have defined your property names and defaults as constant strings you can even do:

  @Provides @Named(PROPERTY_NAME_CONSTANT) String a() {
    props.getProperty(PROPERTY_NAME_CONSTANT, PROPERTY_NAME_CONSTANT_DEFAULT);
  }

它是更多样板,但 Dagger 在试图消除大量样板的同时,更喜欢编译时分析而不是绝对样板减少.也就是说,我将提出一个可以改善这种情况的功能,从已知列表中自动生成系统属性的模块,或者一些类似的功能.我认为即使是这个样板也可以减少.

It is more boiler plate, but Dagger has, while trying to eliminate much boiler plate, preferred compile-time analysis over absolute boiler plate reduction. That said, I'll propose a feature that will improve this situation, auto-generating a module for system properties from a known list, or some such. I think even this boiler plate can be reduced.

这篇关于Dagger:注入@Named 字符串?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆