Как правильно обрабатывать проверенные исключения в конструкторах с Guice? - PullRequest
1 голос
/ 14 сентября 2011

У меня есть код, который выглядит следующим образом:

class A {
  X x;

  A() {
    Class<? extends X> cls = ...;
    Module module = ...;
    Injector injector = Guice.createInjector(module);
    x = injector.getInstance(cls);
  }
}

Конкретный тип cls определяется только во время выполнения и не известен до вызова этого конструктора.

Моя проблема сейчасожидается, что конструкторы cls будут выдавать проверенные исключения, и я хотел бы обработать их (если это возможно, не разворачивая их из ProvisionException).Документация Guice говорит, что я должен использовать расширение бросающих провайдеров, которое кажется здесь сложным.Есть ли более простой способ, чем этот:

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) {
      ...
    }
  }
}

Интерфейс MyCheckedProvider будет в порядке, потому что он будет многократно использоваться в нескольких местах, но мне понадобится отдельный класс ProviderHolder в каждом месте, гдетребуется нечто подобное, и мне нужна конкретная реализация провайдера для каждого класса, реализующего X (которых может быть много).Так что это даже больше, чем просто внедрение XFactory и написание XFactoryImpl для каждого конкретного типа (чего я пытался избежать).

Я надеялся, что смогу сделать что-то вроде

injector.getInstance(new TypeLiteral<MyCheckedProvider<X>>() {});

или

injector.getCheckedProvider(cls, MyCheckedException.class);

, но, похоже, это не поддерживается.

1 Ответ

1 голос
/ 25 августа 2012

Вы хотите использовать класс Key здесь, а не TypeLiteral.Тогда нет необходимости ProviderHolder:

Injector injector = Guice.createInjector(module);
MyCheckedProvider<X> provider = injector.getInstance(new Key<MyCheckedProvider<X>>(){});
try {...
...