Hi,

sorry for such a non-descriptive subject...

TL;DR: is there a way to make the ConfigInjectionTest test in 
https://github.com/Ladicek/guice-config-injection pass just by changing 
PropertiesModule? If not, what parts of my design should be changed?

Longer version: I want to inject configuration values to a class from a 
Properties object. I.e., @Inject @Named and Names.bindProperties. I want to 
support all primitive types, their wrapper types, Strings and Guava's 
Optional of the previous types. The PropertiesModule from the sample 
project does that just fine.

I also want to support default values, in case a Properties object doesn't 
contain some key. I like field injection for that, as I can specify the 
default value nicely -- just by initializing the field. So I can have these 
4 combinations (only for Strings, other types work the same):

@Inject @Named("a") private String a;
@Inject @Named("b") private String b = "default value";
@Inject @Named("c") private Optional<String> c;
@Inject @Named("d") private Optional<String> d = Optional.of("default 
value");

If a key is missing in the Properties object, I want an error to be 
detected in case of the field "a" above (it's mandatory). In all the other 
cases, there is a default value to be applied. In case of "b", the field 
should keep its original value of "default value". In case of "c", a value 
of Optional.absent() should be injected. And in case of "d", the field 
should again keep its original value of Optional.of("default value").

What I'm doing in the sample project is

    bind(new TypeLiteral<Optional<String>>() 
{}).annotatedWith(Named.class).toInstance(Optional.absent());

This solves the case "c", but also breaks case "d", because its value is 
overwritten to Optional.absent(). When it comes to case "b", I have no 
idea. I could do something similar, like

    bind(new TypeLiteral<String>() 
{}).annotatedWith(Named.class).toInstance("");

But that wouldn't actually work. It would overwrite the value of "b" and it 
would suppress an error in case "a".

I would be able to do everything I need if I knew the class that is being 
injected. But in that case, I can just get rid of @Inject and do everything 
by hand, it's not that hard (that of course depends on the lifecycle, but 
fortunately, in the real project, I have the lifecycle under control). 
However, I'd really like to stick with Guice injection, because it does 
good error detection and if I ever needed more complex configuration 
values, esp. of generic types, the handrolled solution would become much 
more complex.

I've seen the OptionalBuilder in the multibindings extension in Guice 
master, but I don't think it would help me. I've also 
seen https://github.com/timboudreau/giulius, which does something very 
similar, but solves the default values differently. I understand that my 
way can only work for field injection and prevents immutability, but that's 
a restriction I can live with.

I'm mostly a Guice newbie, so maybe what I'm trying to do here goes against 
the Guice philosophy. In that case, what would be your advice?

Thank you very much!

LT

-- 
You received this message because you are subscribed to the Google Groups 
"google-guice" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/google-guice.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/google-guice/b44373a0-1c93-4bb8-aecb-0aece614dbbf%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to