I understand that the values are mutable at run time, but do you know the
set of keys up front?
I would create a binding for each key:
for (final String key : keys) {
// replace @Named w/ @Property equivalent
bind(String.annotatedWith(Names.named(key))).toProvider(new
Provider<String>() {
@Inject Registry registry;
public String get() {
return registry.get(key);
}
});
}
You might scope the result, too, so the value doesn't change in the middle
of an HTTP request for example.
If you don't already have a way to determine the set of keys at load time,
you can run an annotation processor (
http://java.sun.com/javase/6/docs/api/javax/annotation/processing/Processor.html)
over your code that finds the @Property annotations and writes the keys to a
file.
The benefit of this approach is that you can check your code at build or
initialization time.
Bob
On Fri, Apr 10, 2009 at 1:35 AM, Aleksey Didik <[email protected]>wrote:
>
> Hello all,
> I have caught one problem and want to ask your advise.
>
> In the my application I have a registry singleton which contains all
> application properties
>
> class Registry {
> String get(String property) {
> //stub
> return "Foo";
> }
> }
>
> Some components of my app need the Registry to work (is a component
> enabled,
> connection timeout and etc), but I don't want to inject the Registry
> itself, it will make components harder to test and not only. I want
> to
> inject properties values from the Registry.
> I have found the Names.bindProperties() solution in Guice FAQ, but
> it's not for me;
> properties in the Registry is not immutable.
>
> The best for me is using an annotation like @Property("foo.name") and
> using the Registry to resolve annotated dependency.
>
> class Foo {
> @Property("foo-name")
> private String name;
> }
>
> With last Guice update I can use a listener binding and register
> MembersInjector in TypeEncounter. MembersInjector allow me to resolve
> all necessary dependencies by myself.
> But it's works only for methods and fields, but I'm a constructor
> injection adept and I want to use a parametrized annotation in
> constructor, for example:
>
> class Foo {
> private final String name;
> @Inject
> public Foo(@Property("foo-name") String name) {
> this.name = name;
> }
> }
>
> Using Provider can't solve my issue, because Provider.get() has no
> information about the dependency injected now.
>
> My proposal is adding to Guice something like KeyedProvider:
>
> interface KeyedProvider<T> {
> String get(Key<T> key);
> }
>
> class PropertyProvider implements KeyedProvider<String> {
> @Inject
> Registry registry;
> public String get(Key<String> key) {
> final Property propertyAnnotation = (Property) key.getAnnotation
> ();
> return registry.get(propertyAnnotation.value());
> }
> }
>
> Module module = new AbstractModule() {
> protected void configure() {
> bind(String.class).annotatedWith
> (Property.class).toKeyedProvider(new PropertyProvider());
> }
> };
>
>
> As to me, it will be very usefull. We can use binding annotations not
> only as markers, but as a set of parameters, as what and how provide
> now.
>
> What do you think about it?
>
> Best regards,
> Aleksey.
>
>
> >
>
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"google-guice" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/google-guice?hl=en
-~----------~----~----~----~------~----~------~--~---