Binding a value to one of two possibilities in Guice

被刻印的时光 ゝ 提交于 2021-01-28 12:03:28

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!