How to nicely handle checked exceptions in constructors with Guice?
I have code that reads like this:
class A {
X x;
A() {
Class<? extends X> cls = ...;
Module module = ...;
Injector injector = Guice.createInjector(module);
x = injector.getInstance(cls);
}
}
The concrete type cls
is determined only at runtime and not known before this constructor is called.
My problem now is that the constructors of cls
are expected to throw checked exceptions, and I'd like to handle them (if possible without unwrapping them from a ProvisionException). The Guice documentation says I should use the throwing providers extension, which seems to be complex here. Is there a simpler way than this:
interface MyCheckedProvider<T> extends CheckedProvider<T> {
T get() throws MyCheckedException;
}
class XImplProvider implements MyCheckedProvider<X> {
@Inject dependency1;
@Inject dependency1;
X get() throws MyCheckedException {
return new XImpl(dependency1, dependency2);
}
}
class ProviderHolder {
@Inject MyCheckedProvider<X> provider;
}
class A {
X x;
A() {
Class<? extends MyCheckedProvider<X>> providerClass = ...;
Module module = new AbstractModule() {
void configure() {
...
ThrowingProviderBinder.create(binder())
.bind(MyCheckedProvider.class, X.class)
.to(providerClass.class);
}
};
Injector injector = Guice.createInjector(module);
ProviderHolder holder = injector.getInstance(ProviderHolder.class);
try {
x = holder.provider.get();
catch (MyCheckedException e) {
...
}
}
}
The interface MyCheckedProvider
would be ok, because it would be reusable in several places, but I'd need a separate ProviderHolder
class at each place where something similar is needed, and I need a specific provider implementation for each class implementing X (of which there could开发者_高级运维 be many). So this is even more work than just injecting an XFactory and writing an XFactoryImpl for each concrete type (which I tried to avoid).
I had hoped that I can do something like
injector.getInstance(new TypeLiteral<MyCheckedProvider<X>>() {});
or
injector.getCheckedProvider(cls, MyCheckedException.class);
but it seems this is not supported.
You want to use the Key
class here, not TypeLiteral
. Then there is no need for ProviderHolder
:
Injector injector = Guice.createInjector(module);
MyCheckedProvider<X> provider = injector.getInstance(new Key<MyCheckedProvider<X>>(){});
try {...
精彩评论