25

I'am trying to Inject generic type with Guice. I have Repository< T > which is located in the Cursor class.

public class Cursor<T> {

    @Inject
    protected Repository<T> repository;

So when I create Cursor< User >, I also want the Guice to inject my repository to Repository< User >. Is there a way to do this?

petomalina
  • 2,020
  • 2
  • 19
  • 25

1 Answers1

32

You have to use a TypeLiteral:

import com.google.inject.AbstractModule;
import com.google.inject.TypeLiteral;

public class MyModule extends AbstractModule {

  @Override
  protected void configure() {
    bind(new TypeLiteral<Repository<User>>() {}).to(UserRepository.class);
  }
}

To get an instance of Cursor<T>, an Injector is required:

import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.TypeLiteral;

public class Main {

  public static void main(String[] args) {
    Injector injector = Guice.createInjector(new MyModule());
    Cursor<User> instance = 
        injector.getInstance(Key.get(new TypeLiteral<Cursor<User>>() {}));
    System.err.println(instance.repository);
  }
}

More details in the FAQ.

dimo414
  • 47,227
  • 18
  • 148
  • 244
gontard
  • 28,720
  • 11
  • 94
  • 117
  • I thought the same, but did you try that out? I got `Repository cannot be used as a key; It is not fully specified`. – steffen Jul 09 '14 at 15:17
  • I often use this kind of configuration without any problem. And i provide some links to the guice documentation – gontard Jul 09 '14 at 15:18
  • The thing is, I need the constructor to the UserRepository to be injected. So there's no way to call Guice.createInjector – petomalina Jul 09 '14 at 15:22
  • The entry point of guice is the injector. How do you want to use guice without it ? – gontard Jul 09 '14 at 15:23
  • The difference between the examples in the guice documentation and the problem here is (guice documentation) `Collection` vs. (here) `Collection`. While the former can be injected, the latter gives the error message above. So did you try it out with something like `Collection`? – steffen Jul 09 '14 at 15:25
  • @steffen In this case, @Gelidus needs to bind a `Repository` to a `UserRepository`. There is no need to bind a `Repository`. If you want to bind a `Collection` to an `ArrayList`, you could simply do `bind(Collection.class).to(ArrayList.class)`. – gontard Jul 09 '14 at 15:28
  • You're right, in my test scenario was a circular reference :-/ – steffen Jul 09 '14 at 15:34
  • i know this is old, but i have what really feels like the same problem here: http://stackoverflow.com/questions/40646780/dependency-injection-using-guice-with-the-dao-pattern and i'm struggling to figure it out. can anyone provide guidance? – Justin Nov 18 '16 at 02:49
  • What if I do not have an interface and implementation scenario? I just have one class, `Repository` and I need it to be injected in another class `Cursor`? I have bind them both like this: `bind(new TypeLiteral>() {});` `bind(new TypeLiteral>() {});` But I still get the `cannot be used as a key; It is not fully specified.` error – rrrocky Apr 04 '18 at 11:22
  • new to guice, if I bind Repository to Repository.class, then what would I do if I need to provide another type such as Repository, what should I bind to ? – user2386301 Aug 22 '20 at 21:12
  • My generic type is comes from a package-private class and is therefore invisible to the module. Anyway to bind this? – Cardinal System Mar 24 '23 at 13:45