记住所有的configure
方法在Injector
注射前的任何可能发生配置绑定的所有。这就是说,几件事情:
绑定@Named
性质单一Properties
实例的内容是非常有用,有一个Names.bindProperties(...)
方法自动为您完成。唯一的窍门是,您需要在configure()
运行时有Properties
实例。
如果它们全都可用,则不必担心绑定一个模块中的属性并将应用程序绑定到另一个模块中。只要他们都进入相同的Injector
,吉斯将他们全部结合起来,让他们满足彼此的依赖。
提供者可以返回不同的实例,而且通常会这样 - 但是你说得对,它不会帮助你区分键。如果直接注射Properties实例是太丑陋了,考虑制定一个轻量级的工厂,而不是:
public class ConfigOracle {
@Inject private Properties properties;
public String getAsString(String key) { ... }
public int getAsInt(String key) { ... }
}
public class SomeConfigUser {
@Inject private ConfigOracle configOracle;
public void doStuff() {
doStuffBasedOn(configOracle.getAsString("my.properties.key"));
}
}
你不应该需要注入Binder
(或其他东西)到模块。
- 如果实现
Module
,该binder
将是configure()
的参数。如果扩展AbstractModule
,你应该,只需调用binder()
方法。
- 您可以通过依赖构造函数参数的模块通过,如果需要的话,它(就我而言)是唯一的出路模块应该改变他们所创造的绑定。
- 没有理由你无法通过喷油器创建一个模块,但你必须先有一个喷油器,这听起来像你想用只有一脱身。
- 如果您需要注入器的其他实例,您总是可以使用
@Inject
字段/方法/构造函数编写Provider
实现,甚至可以使用@Provides
方法(将为filled in with dependencies automatically)写入参数。
总的来说,我还是赞成孩子注射的方法(感谢您的链接,并称赞我以前的答案!),它适合您“的基础上注入的情况下动态绑定”介绍最好的,而且会从字面上这么简单:
class PropertiesModule extends AbstractModule {
Properties properties;
PropertiesModule(Properties properties) {
this.properties = properties;
}
@Override public void configure() {
Names.bindProperties(binder(), properties);
}
}
Injector oldInjector = Guice.createInjector(allYourOtherModules);
Module myModule = new PropertiesModule(oldInjector.get(Properties.class));
Injector injector = oldInjector.createChildInjector(myModule);
另外一个很好的答案,谢谢!我不知道Names.bindProperties()方法,我必须为后者保存。我尝试了你昨晚在2号提出的解决方案,它大部分工作,虽然并不像我本来喜欢的那样干净。我基本上得出的结论是,我真正想做的事情不属于Guice的设计。我没有,我在部署框架,我不相信孩子注射器将可用特征很快,所以我会有点不同返工我们的配置。尽管谢谢你的及时答复! –