Using Guice 3.0, I try to inject a Provider that can throw specific checked exceptions. So I use the Throwing Providers extension.
I created an interface for the Provider :
public interface IMyProvider<T> extends CheckedProvider<T>
{
@Override
T get() throws MyException;
}
And its implementation :
public class MyProvider implements IMyProvider<List<SomeType>>
{
@Override
public List<SomeType> get() throws MyException
{
//...
}
}
I use the @Inject annotation on the object where I want to inject the Provider :
@Inject
public SomeConstructor(IMyProvider<List<SomeType>> myProvider)
{
//...
}
Now, my problem is : how to bind this Provider?
Since generics are used, I though about using TypeLiteral
:
bind(MyProvider.class);
ThrowingProviderBinder.create(binder())
.bind(IMyProvider.class, new TypeLiteral<List<SomeType>>(){})
.to(MyProvider.class);
But it seems TypeLiteral
is not a valid argument for this bind() method.
Am I missing something?
UPDATE :
I found a workaround. By creating a class that extends ArrayList<SomeType>
, I'm able to bind the Provider :
public class SomeTypeList extends ArrayList<SomeType>
and
bind(MyProvider.class);
ThrowingProviderBinder.create(binder())
.bind(IMyProvider.class, SomeTypeList.class)
.to(MyProvider.class);
But it would be easier if that SomeTypeList
class wouldn't be required!
You're looking for a Type
instance, which TypeLiteral
does not natively implement.
I haven't worked with this directly, but Guice does provide a Types
class, and there is also a method TypeLiteral.getType
. Try one of the following:
Types.listOf(SomeType.class)
Types.newParameterizedType(List.class, SomeType.class)
(new TypeLiteral<List<SomeType>>() {}).getType()
My preference is the first, which would look like this:
ThrowingProviderBinder
.create(binder())
.bind(IMyProvider.class, Types.listOf(SomeType.class))
.to(MyProvider.class);