问题
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?
回答1:
Your first design seems like the best option to me if you don't need the binding to change at runtime (i.e. the binding is constant as of injector creation time).
For any value you decide at runtime, you'll need a Provider or a @Provides
method:
public class SimpleIfBlockModule extends AbstractModule {
@Override public void configure() { }
@Provides @Named("foo") String provideFoo(
@Named("Default foo") String defaultFoo,
AnyInjectableDependencyHere ifNeeded) {
if (System.getProperties().containsKey("foo")) {
return System.getProperty("foo");
} else {
return defaultFoo;
}
}
}
If you need to decide at runtime based on a parameter, use this solution.
来源:https://stackoverflow.com/questions/24193591/binding-a-value-to-one-of-two-possibilities-in-guice