I would like to be able to inject a generic implementation of a generic interface using Guice.
public interface Repository<T> {
void save(T item);
T get(int id);
}
public MyRepository<T> implements Repository<T> {
@Override
public void save(T item) {
// do saving
return item;
}
@Override
public T get(int id) {
// get item and return
}
}
In C# using Castle.Windsor, I'd be able to do:
Component.For(typeof(Repository<>)).ImplementedBy(typeof(MyRepository<>))
but I don't think the equivalent exists in Guice. I know I can use TypeLiteral
in Guice to register individual implementations, but is there any way to register them all at once like in Windsor?
Edit:
Here's an example of usage:
Injector injector = Guice.createInjector(new MyModule());
Repository<Class1> repo1 = injector.getInstance(new Key<Repository<Class1>>() {});
Repository<Class2> repo2 = injector.getInstance(new Key<Repository<Class2>>() {});
Although the more likely usage would be injection into another class:
public class ClassThatUsesRepository {
private Repository<Class1> repository;
@Inject
public ClassThatUsesRepository(Repository<Class1> repository) {
this.repository = repository;
}
}
In order to use generics with Guice you need to use the TypeLiteral class to bind the generic variants. This is an example of how you're Guice injector configuration could look like:
package your-application.com;
import com.google.inject.AbstractModule;
import com.google.inject.TypeLiteral;
public class MyModule extends AbstractModule {
@Override
protected void configure() {
bind(new TypeLiteral<Repository<Class1>>(){})
.to(new TypeLiteral<MyRepository<Class1>>(){});
}
}
(Repository is the generic interface, MyRepository is the generic implementation, Class1 is the specific class used in the generics).