Generic injection with roboguice
I am trying to inject instances using generics and I am getting the following error:
HasOne<ModelClass> cannot be used as a key; It is not fully specified.
I've read elsewhere that a safe way to do this is to explicitly specify the class to be used in a generic format when using an injector to get an instance, but I'd like to be a little cleaner. I am trying to create objects in Relationship
between Models
.
Here is my simplified Model
class
public class Model {
@Inject
Injector injector;
public <ModelClass extends Model> HasOne<ModelClass> hasOne(Class<ModelClass> clazz) {
HasOne<ModelClass> hasOne = injector.getInstance(Key.get(new TypeLiteral<HasOne<ModelClass>>() {
}));
hasOne.init(clazz);
return hasOne;
}
}
My relationship HasOne
public class HasOne<T extends Model> {
Class clazz;
public void init(Class<T> clazz){
this.clazz = clazz;
}
@Inject
Injector injector;
public T get(){
return (T) injector.getInstance(clazz);
}
}
Test Model
# 1
public class TestModel extends Model {
public HasOne<ExampleModel> exampleModel(){
return hasOne(ExampleModel.class);
}
}
Test Model
# 2
public class ExampleModel extends Model {
}
I am getting error while doing this
TestModel testModel = RoboGuice.getInjector(context).getInstance(TestModel.class);
HasOne<ExampleModel> relationship = testModel.exampleModel();
I am trying to hide the ugly relationship creation and keep it in class Model
source to share
You cannot use new TypeLiteral<T>() { }
if T
is a type parameter, it must be a fully qualified type. Fortunately, since you have an instance Class<ModelClass>
, you can do this:
(Key<HasOne<ModelClass>>) Key.get(TypeLiteral.get(Types.newParameterizedType(HasOne.class, clazz)))
You will receive a throw warning, but it is safe to suppress it.
source to share