This is not feasible with Guice idiomatically, and this is not his main focus.
jfpoilpret said everything that can be said, but I would like to approach the problem from a different direction, where you have the opportunity (possibly) to solve your problem, having lost type safety.
So in your code, you are asking Guice to get an instance of your Runner<T, V> class, like this
injector.getInstance(Runner.class);
but this cannot be resolved by Guice, because Runner<T, V> has a dependency on GenericDAO<T, V> , but you did not bind the exact implementation to it. As jfpoilpret said, you need to link some specific implementations for it in your module.
I assume that you want to determine the exact implementation of GenericDAO<T, V> that you pass to your Runner<T, V> based on some input whose data type is unknown at compile time. Now suppose you have two implementations.
bind(new TypeLiteral<GenericDAO<String, ObjectID>>(){}).to(StringDAO.class); bind(new TypeLiteral<GenericDAO<Double, ObjectID>>(){}).to(IntegerDAO.class);
Based on different types of inputs you can do this
Injector injector = Guice.createInjector(new RunnerModule()); // possible input which you get from *somewhere* dynamically Object object = 1.0; TypeLiteral<?> matchedTypeLiteral = null; for (Key<?> key : injector.getAllBindings().keySet()) { TypeLiteral<?> typeLiteral = key.getTypeLiteral(); Type type = typeLiteral.getType(); if (type instanceof ParameterizedType) { ParameterizedType parameterizedType = (ParameterizedType) type; if (parameterizedType.getRawType() == GenericDAO.class) { List<Type> actualTypeArguments = Arrays.asList(parameterizedType.getActualTypeArguments()); if (actualTypeArguments.get(0) == object.getClass()) matchedTypeLiteral = typeLiteral; } } }; Runner<?, ?> runner = new Runner<>((GenericDAO<?, ?>) injector.getInstance(Key.get(matchedTypeLiteral))); System.out.println(runner.dao.getClass()); // IntegerDAO.class
If Object object = "string"; then another implementation will be found. This, of course, is pretty ugly and could be improved with checking subclasses and stuff, but I think you get the idea. The bottom line is that you cannot get around this.
If you manage to do this (get around this), write me an email, because I would like to know about it! I encountered the same problem that you have been facing not so long ago. I wrote a simple BSON codec where I wanted to load certain implementations of a universal interface based on the type of some arbitrary input. This affected Java-BSON mappings well, but I couldn't do it the other way around in a reasonable way, so I chose a simpler solution.