开发者

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 {...
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜