one instance per type&annotation

5 views
Skip to first unread message

med...@gmail.com

unread,
May 28, 2008, 11:58:07 AM5/28/08
to google-guice
I would like to do something like:

@AnnotationSingleton
class Myclass
{
}

That is, I'd like to have a class which Guice provides a singleton
instance of for each annotation. Ex. as a client:

@Inject @MyAnno1 Myclass x;
@Inject @MyAnno2 Myclass y;
@Inject @MyAnno1 Myclass z;

x and z would be the same instance, but y would be different.
Additionally, it'd be nice to support this:

@Inject @Named("a1") Myclass x;
@Inject @Named("a2") Myclass y;
@Inject @Named("a1") Myclass z;

Again, x and z would be the same instance, but not y.

Sam Berlin

unread,
May 28, 2008, 12:19:10 PM5/28/08
to google...@googlegroups.com
It is possible to do this by setting up the bindings (we infact do
this in Guice 1.0). The binding would be setup like:

bind(X.class).annotatedWith(A1.class).to(XImpl1.class).in(Scopes.SINGLETON);
bind(X.class).annotatedWith(A2.class).to(XImpl2.class).in(Scopes.SINGLETON);

Then you can:
@Inject @A1 X x1;
@Inject @A2 X x2;

You can't use @Singleton as an annotation in the Impl's class
definition because you need to define the singleton scope separately
per annotation.

Sam

med...@gmail.com

unread,
May 28, 2008, 12:35:25 PM5/28/08
to google-guice
The problem is that do not know the annotation types at compile time.
I want to allow clients to create their own annotations (or use
@Named) and use them with the guarantee that if they use the same one
in two or more places, they'll get the same instance injected. And
the clients shouldn't have to do any binding themselves.

On May 28, 10:19 am, "Sam Berlin" <sber...@gmail.com> wrote:
> It is possible to do this by setting up the bindings (we infact do
> this in Guice 1.0).  The binding would be setup like:
>
>  bind(X.class).annotatedWith(A1.class).to(XImpl1.class).in(Scopes.SINGLETON);
>  bind(X.class).annotatedWith(A2.class).to(XImpl2.class).in(Scopes.SINGLETON);
>
> Then you can:
>  @Inject @A1 X x1;
>  @Inject @A2 X x2;
>
> You can't use @Singleton as an annotation in the Impl's class
> definition because you need to define the singleton scope separately
> per annotation.
>
> Sam
>

med...@gmail.com

unread,
May 29, 2008, 11:45:52 AM5/29/08
to google-guice
I think it would require information that only Guice knows; details
about the injection spot. Like, I could do it with a Provider that
somehow had access to all the annotations of the field being injected,
but I don't think that's possible. Perhaps it'd require a
modification to Guice: would someone with knowledge of Guice internals
verify?

Stuart McCulloch

unread,
May 29, 2008, 12:09:30 PM5/29/08
to google...@googlegroups.com
2008/5/29 med...@gmail.com <med...@gmail.com>:

I think it would require information that only Guice knows; details
about the injection spot.  Like, I could do it with a Provider that
somehow had access to all the annotations of the field being injected,
but I don't think that's possible.  Perhaps it'd require a
modification to Guice: would someone with knowledge of Guice internals
verify?

yes, at the moment you'd need to patch Guice to get this.

for example, this patch adds support for binding factories:

  http://code.google.com/p/peaberry/wiki/Patch_BindingFactory

which lets you add bindings dynamically during creation of
the injector, but for safety/sanity keeps bindings immutable
once the injector has been built

this unofficial patch builds against guice trunk (most days ;)
 



--
Cheers, Stuart

Robbie Vanbrabant

unread,
May 29, 2008, 6:36:24 PM5/29/08
to google...@googlegroups.com
Maybe you can figure something out with providers? Like, provide an easy way for API consumers to create no-scope providers with existing keys.

bind(Blah.class).annotatedWith(UserAnnotation.class).toProvider(Provider.from(Key.get(Blah.class,API.class));

That generated Provider then delegates to the correctly scoped one:
@Inject Injector i;
return i.getInstance(key);

With some conventions, you could reduce configuration for users further:
register(Blah.class, MyAnnotation.class)

Not sure if it's going to work, but it might be worth a try.

Robbie
Reply all
Reply to author
Forward
0 new messages