Is there any good reason Key.get(Class<T> type) doesn't create a unique instance by default?

28 views
Skip to first unread message

glenviewjeff

unread,
Dec 31, 2011, 4:31:48 PM12/31/11
to google...@googlegroups.com
I have binding code all over that looks like this, so much so that I derived an AbstractModuleWithBindingHelpers from AbstractModule to help cut some of the code clutter. 

   private static final Key<Boolean> TRUE_KEY = Key.get(Boolean.class, randomAnnotation());
   private static final Key<Boolean> FALSE_KEY = Key.get(Boolean.class, randomAnnotation());

   protected static Named randomAnnotation() {
      return Names.named(UUID
            .randomUUID().toString());
   }

Why doesn't Key.get(Class<T> type) just do this by default?  I suppose this could help with debugging if someone accidentally requests a key on the same type more than once, but I would think that the value added in writing more concise code would be preferable.

Colin Decker

unread,
Jan 1, 2012, 11:15:50 AM1/1/12
to google...@googlegroups.com
Because that's not at all what Key.get(Class) is intended to do. Key is an abstraction of an injectable type (either a raw Class or a generic TypeLiteral), possibly with an associated binding annotation to differentiate it from other Keys for the same type. Key.get(Class) is for creating a Key representing a class with no binding annotation, which must be equal to any other Key for the same class with no binding annotation. I also think that what you're doing is something that should be needed only very rarely in Guice applications, so it would be harmful to make it easier.

-- 
Colin


--
You received this message because you are subscribed to the Google Groups "google-guice" group.
To view this discussion on the web visit https://groups.google.com/d/msg/google-guice/-/k2SOvuk58REJ.
To post to this group, send email to google...@googlegroups.com.
To unsubscribe from this group, send email to google-guice...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/google-guice?hl=en.

glenviewjeff

unread,
Jan 2, 2012, 1:36:48 PM1/2/12
to google...@googlegroups.com
Hi Colin:

I'm putting together a little article about designing what I believe to be good Guice binding architecture.  It makes heavy use of Gimlet's LegProvider for solving the robot legs problem.  I'll probably ask you to review it if you don't mind before I post it.

In the meantime, I'm now using code like this to make my bindings more readable:

   private static final Key<Boolean> TRUE_KEY = getUniqueKey(Dashboard.class);

Where getUniqueKey is defined inside AbstractModuleWithBindingHelpers:

   protected <T> Key<T> getUniqueKey(Class<T> superClass) {

      Key<T> key =
       Key.get(superClass, Names.named(UUID.randomUUID().toString()));
      return key;
   }


glenviewjeff

unread,
Jan 2, 2012, 1:37:26 PM1/2/12
to google...@googlegroups.com
Sorry, that should have read:

private static final Key<Boolean> TRUE_KEY = getUniqueKey(Boolean.class);

Sam Berlin

unread,
Jan 2, 2012, 3:11:30 PM1/2/12
to google...@googlegroups.com
FYI, there's a class hidden away in com.google.inject.internal.UniqueAnnotations that does this (in a slightly cleaner/simpler way).  It's in internal, so not part of the public API and is subject to change/moving/deletion/etc... but so many folks use it that it's probably worthwhile promoting it to c.g.i.util.  Note, though, that it's just a unique *annotation*, not a unique key.  Key is still a combination of a TypeLiteral & a binding annotation, as Colin mentioned.  So you'd use something like Key.get(YourClass.class, UniqueAnnotations.create()) instead of a helper getUniqueKey(Class) method, which I'd argue is a little more understandable and keeps the concepts well-separated.

sam


   }


--
You received this message because you are subscribed to the Google Groups "google-guice" group.
To view this discussion on the web visit https://groups.google.com/d/msg/google-guice/-/CqHe6A5yH6cJ.
Reply all
Reply to author
Forward
0 new messages