views:

332

answers:

1

Guice provides a means to find all bindings for a given type (Injector#findBindingsByType) and it also provides a TypeLiteral class from which it seems possible to construct a wildcard type. What I would like to do is find all bindings for some type that is parameterised by a wildcard type but I can't figure out how to do it. A look at the guice src suggests I might be barking up the wrong tree but I figured I'd ask around anyway... so for example given a type

Foo<E extends Bar>
BarImplOne implements Bar
BarImplTwo implements Bar

and some bindings like

bind(new TypeLiteral<Foo<BarImplOne>>() {}).to(MyFooOne.class);
bind(new TypeLiteral<Foo<BarImplTwo>>() {}).to(MyFooTwo.class);

then I want to be able to discover both bindings with something like

Injector.findBindingsByType(TypeLiteral.get(Types.newParameterizedType(Foo.class, Types.subtypeOf(Bar.class))));

Any ideas?

Cheers Matt

+1  A: 

Unfortunately, there's no out-of-the-box API that will tell you whether one TypeLiteral is assignable from another. You'll need to do an old-school loop with a bunch of hideous instanceof checks. Something gross like this:

for (Map.Entry<Key<?>, Binding<?>> entry 
    : injector.getBindings().entrySet()) {
  Type type = entry.getKey().getTypeLiteral().getType();
  if (!(type instanceof ParameterizedType)) continue;

  ParameterizedType parameterized = (ParameterizedType) type;
  if (parameterizedType.getRawType() != Foo.class) continue;

  Type parameter = .getActualTypeArguments()[0]
  if (!(parameter instanceof Class)) continue;

  Class<?> parameterClass = (Class<?>) parameter;
  if (!Bar.class.isAssignableFrom(parameterClass)) continue;

  results.add(entry);
}

Of course, it would be much nicer to do something using an off-the-shelf API. I'd welcome an contribution to Guice that implements and tests TypeLiteral.isAssignableFrom(TypeLiteral). Contact our user's list to volunteer!

Jesse Wilson
thanks for the pointer, I have a quite simple version (based on the above) working that fits my immediate needs but I'll try and make a more general case that deals with a few more situations and post it to the list.
Matt