Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Guice generics - how can I make it less ugly?

I have an interface Producer<T> and a concrete FooProducer that implements Producer<Foo>. Binding this in guice looks ugly as sin:

bind(new TypeLiteral<Producer<Foo>>() {}).to(FooProducer.class);

I have lots of these such bindings. I have tried the following:

static <T> TypeLiteral<Producer<T>> producer() {
    return new TypeLiteral<Producer<T>>(){};
}

With calls made in this way:

bind(ContainingClass.<Foo>producer()).to(FooProducer.class);

But it gives an error along the lines of Producer<T> is not specific enough....

Am I going about this in the wrong way?

like image 781
Finbarr Avatar asked Sep 23 '10 10:09

Finbarr


2 Answers

Instead of

bind(new TypeLiteral<Producer<Foo>>() {}).to(FooProducer.class);

try a convenience method like

static <T> Key<Producer<T>> producerOf(Class<T> type) {
  return (Key<Producer<T>>)Key.get(Types.newParameterizedType(Producer.class,type));
}

and then in your module

bind(producerOf(Foo.class)).to(FooProducer.class);

That unchecked cast should be safe. Key is com.google.inject.Key and Types is com.google.inject.util.Types.

good luck

like image 105
Darren Gilroy Avatar answered Sep 19 '22 16:09

Darren Gilroy


You can save 8 characters by typing new Key<Producer<Foo>>(){} rather than new TypeLiteral<Producer<Foo>>(){}. Or by using the equivalent @Provides method:

@Provides
public Producer<Foo> provideFooProducer(FooProducer fooProducer) {
  return fooProducer;
}
like image 24
Jesse Wilson Avatar answered Sep 22 '22 16:09

Jesse Wilson