I want to inject an object of a generic interface type into another object
class InjectionTarget {
@Inject IGenericType<String, Integer> object;
}
interface IGenericType<A, B> {
void foo(A a);
void bar(B b);
}
class GenericTypeImpl<A, B> implements IGenericType<A, B> {
List<A> someListA = new ArrayList();
List<B> someListB = new ArrayList();
@Override
public void foo(A a) {
someListA.add(a);
}
@Override
public void bar(B b) {
someListB.add(b);
}
}
// dagger component and actual injection skipped for clarity
I tried to use a provider method, but it causes compilation error (@Provides methods may not have type parameters)
@Module
class Module {
// this doesn't compile
@Provides
<A, B> IGenericType<A, B> getGenericType() {
return new GenericTypeImpl<A, B>();
}
}
So I had to move type parameters from @Provides method to class. Then, since:
- Modules with type parameters must be abstract
- abstract module cannot have instance @Provides methods (all must be static)
- non-static type variable A and B cannot be referenced from a static context
I cannot use @Provides method anymore (even static one, because of type variables), so I ended up with @Binds using @Inject constructor for implementation
@Module
public abstract class TestModule<A, B> {
@Binds
abstract IGenericType<A, B> getGenericType(GenericTypeImpl<A, B> object);
}
class GenericTypeImpl<A, B> implements IGenericType<A, B> {
...
@Inject
public GenericTypeImpl() {}
...
}
but this fails too with
IGenericType<java.lang.String,java.lang.Integer> cannot be provided without an @Provides-annotated method
So it seems a hopeless case. Is there any way to workaround this ? I prefer to avoid adding provider methods for every single type combination I'll use (I expect there will be many of these) and stay with one generic provider/binds method.