I have a generic abstract template class. I thought if I create type-specific Producers, I could inject some DAO service directly in the generic class. But I can't.
Why? And how could I work around this?
abstract class MyView<T> {
@Inject
MyDao<T> dao;
//some more template methods that make use of the dao
void someMethod() {
dao.use();
}
}
class CustomerView extends MyView<Customer> {
//javax.enterprise.inject.AmbiguousResolutionException: Ambigious resolution
}
class DaoManager {
@Produces
MyDao<Customer> getDaoCustomer() {
return DaoFactory.make(Customer.class);
}
@Produces
MyDao<Product> getDaoProduct() {
return DaoFactory.make(Product.class);
}
}
When I inject eg a @Inject MyDao<Customer> dao;
it works perfectly. But not with generics...
When you request
the container knows that you want a bean specifically of type
MyDao<Customer>
. If such a bean exists and its type information is known, then the container can satisfy the injection. For example, the type information is preserved in your@Produces
annotated methodThe container uses reflection to retrieve that parameterized type and can match it to the requested
@Inject
field.With
however, all the container knows is that you want a
MyDao
.T
is a type variable, not a concrete parameterization. The container cannot assume a specific type for it. In your case, both of the@Produces
beans would match and there would be ambiguity.In your example, we know from the context that it really wants a
MyDao<Customer>
. That doesn't seem to be something your container is capable of doing, ie. trying to resolve the type parameter to a concrete type argument for a parameterized subclass.