2

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?

Kelvin Chung
  • 1,327
  • 1
  • 11
  • 23

1 Answers1

3

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.

Community
  • 1
  • 1
Jeff Bowman
  • 90,959
  • 16
  • 217
  • 251