OptionalBinding использует Guice, чтобы избежать привязки пользователями - PullRequest
0 голосов
/ 31 января 2020

В соответствии с документацией OptionalBinder

API для привязки необязательных значений, необязательно со значением по умолчанию. OptionalBinder выполняет две роли:

  1. Позволяет платформе определять точку внедрения, которая может или не может быть привязана пользователями.
  2. Позволяет платформе предоставлять значение по умолчанию, которое может быть измененным пользователями.

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

interface Reporting<R> {} // service to be bind optionally

class InternalServiceImpl implements InternalService {
    @Inject
    Reporting reporting;
    ... // use this in a method
}

public class FrameworkModule extends AbstractModule {
   protected void configure() {
     OptionalBinder.newOptionalBinder(binder(), Reporting.class);
   }
}

в пользовательских модулях ( class UserWorkingModule) если я не предоставляю привязку, такую ​​как

bind(new TypeLiteral<Reporting<ReportingEvent>>(){}).to(ReportingImpl.class).in(Singleton.class);

, приложение не запускается со следующими журналами:

1) No implementation for Reporting was bound.   while locating Reporting
    for field at InternalServiceImpl.reporting(InternalServiceImpl.java:21) at
FrameworkModule.configure(FrameworkModule.java:55) (via modules: UserWorkingModule -> FrameworkModule)

Обязательно ли предоставлять привязку для Reporting в UserWorkingModule?

1 Ответ

1 голос
/ 01 февраля 2020
bind(new TypeLiteral<Reporting<ReportingEvent>>(){}).to(ReportingImpl.class).in(Singleton.class);

является привязкой для универсального c Reporting<ReportingEvent>, в то время как

OptionalBinder.newOptionalBinder(binder(), Reporting.class);

фактически указывает необработанный тип Reporting. Вместо этого вы хотите использовать перегрузку для newOptionalBinder, которая указывает аргумент TypeLiteral , так что вы говорите об одном и том же в необязательном запросе и в привязке:

OptionalBinder.newOptionalBinder(binder(), new TypeLiteral<Reporting<ReportingEvent>>(){});

Без этого вы в основном говорите, что «любое связывание с отчетностью будет удовлетворять этому требованию», даже что-то вроде Reporting<Object> - и что будет, если связать больше одного?


С другой стороны, если вы на самом деле хотите разрешить любое связывание любого типа Reporting (что и предполагает ваша ошибка, тогда вместо этого происходит обратное: вместо привязки к raw Reporting, вы указали вместо этого generi c impl. Измените этот вызов bind (), сказав, что «на самом деле это работает только для необработанных запросов»:

bind(Reporting.class).to(ReportingImpl.class).in(Singleton.class);
...