Binding a value to one of two possibilities in Guice
- by Kelvin Chung
Suppose I have a value for which I have a default, which can be overridden if System.getProperty("foo") is set. I have one module for which I have
bindConstant().annotatedWith(Names.named("Default foo")).to(defaultValue);
I'm wondering what the best way of implementing a module for which I want to bind something annotated with "foo" to System.getProperty("foo"), or, if it does not exist, the "Default foo" binding.
I've thought of a simple module like so:
public class SimpleIfBlockModule extends AbstractModule {
@Override
public void configure() {
requireBinding(Key.get(String.class, Names.named("Default foo")));
if (System.getProperties().containsKey("foo")) {
bindConstant().annotatedWith(Names.named("foo")).to(System.getProperty("foo"));
} else {
bind(String.class).annotatedWith(Names.named("foo")).to(Key.get(String.class, Names.named("Default foo")));
}
}
}
I've also considered creating a "system property module" like so:
public class SystemPropertyModule extends PrivateModule {
@Override
public void configure() {
Names.bindProperties(binder(), System.getProperties());
if (System.getProperties().contains("foo")) {
expose(String.class).annotatedWith(Names.named("foo"));
}
}
}
And using SystemPropertyModule to create an injector that a third module, which does the binding of "foo". Both of these seem to have their downsides, so I'm wondering if there is anything I should be doing differently. I was hoping for something that's both injector-free and reasonably generalizable to multiple "foo" attributes. Any ideas?