Напиток/Джин.Как внедрить несколько реализаций

StackOverflow https://stackoverflow.com/questions/8379247

  •  28-10-2019
  •  | 
  •  

Вопрос

У меня есть веб-приложение, которое использует GIN для внедрения зависимостей в точке входа.

private InjectorService injector = GWT.create(InjectorService.class);

@GinModules({PlaceContollerInject.class, RootViewInject.class})
public interface InjectorService extends Ginjector {

  RootView getRootView();
  PlaceController getPlaceConroller();

}

public class RootViewInject extends AbstractGinModule {

  @Override
  protected void configure() {
    bind(RootView.class).to(RootViewImpl.class);
  }
}

Мне нужна мобильная версия, которая использует другую реализацию rootView.Зависимости описаны в следующем модуле

public class RootViewMobileInject extends AbstractGinModule {

  @Override
  protected void configure() {
    bind(RootView.class).to(RootViewMobileImpl.class);
  }
}

Вопрос в том, как условно выбрать нужную зависимость, нужна ли нам мобильная версия или версия по умолчанию.Я видел Множество реализаций GWT-GIN, но я не нашел этого решения, потому что Поставщик разрывает цепочку зависимостей, а Заводской шаблон нарушает тестируемость.В видео "Большая модульная Java с Guice" здесь (12 минут) Инжектор Guice с модулями был представлен заводам в качестве замены.Итак, мой вопрос в том, должен ли я создать другой Ginjector для мобильных версий и версий по умолчанию (например, MobileFactory и DefaultFactory) моего приложения, или это было бы плохой практикой, и я должен настроить один экземпляр Ginjector со всеми необходимыми версиями.Например, с привязками аннотаций, подобными этой.

public class RootViewMobileInject extends AbstractGinModule {

  @Override
  protected void configure() {
    bind(RootView.class).annotatedWith(Mobile.class).to(RootViewMobileImpl.class);
  }
}

и используйте аннотированные привязки @Mobile в точке входа GWT

  @Inject
  private void setMobileRootView(@Mobile RootView rw) {
    this.rw = rw;
  }

В таком упрощенном примере, как приведенный выше, это может быть возможно.Но если у приложения больше зависимостей, которым нужны мобильные версии и версии по умолчанию.Похоже, это возвращение к непроверяемым "уродливым" (как было сказано на презентации Guice) фабрикам.Извините за мой английский.Любая помощь приветствуется.

Это было полезно?

Решение

Я полагаю, вы захотите использовать отложенную привязку GWT, используя замену класса для привязки другой версии вашего InjectorService в зависимости от пользовательского агента.Это гарантирует, что в мобильной версии будут скомпилированы (и загружены) только мобильные реализации

Таким образом, у вас были бы InjectorServiceDesktop, InjectorServiceMobile, которые оба расширяются от InjectorService, затем GWT.create(InjectorService.class ), и пусть отложенная привязка решит, какую реализацию ей следует использовать.

http://code.google.com/webtoolkit/doc/latest/DevGuideCodingBasicsDeferred.html#replacement

Один экземпляр Ginjector со всеми версиями кажется плохим, поскольку это означает, что весь код для обеих версий всегда загружается (и вы, конечно, не хотите загружать все свои представления на рабочем столе в свое мобильное приложение)

Редактировать:Как указывает Томас в комментариях, поскольку инжекторы являются сгенерированными классами, вам нужно будет поместить каждый InjectorServiceXXX внутри простого класса holder, который использует GWT.create() InjectorServiceXXX, и используйте замену для переключения между держателями.

Другие советы

Делать то, что вы хотите, на самом деле довольно сложно, потому что ваш общий интерфейс инжектора, который аннотирован вашим модулем джина, не может указывать на абстрактный модуль джина. Модуль джина, на который указал ваш интерфейс Ginjector, должен быть конкретным. Конкретный модуль не может удовлетворить несколько конфигураций одновременно.

Итак, вы делаете: (а) Создайте свой интерфейс Ginjector, скажем, ClientGinjector и ваш модуль ClientModule, для настольного приложения.

(b) Создайте второй интерфейс Ginjector, скажем, Clientginjectortablet, расширяя тот, который вы создали в (а), но с помощью аннотации джинмодуля, указывающей на различный модуль, скажем, ClientModuleTablet.

- Теперь у вас есть два интерфейса Ginjecor один и вторичный для планшетов, каждый из которых указывает на модуль со своими собственными реализациями configure ().

(c) Теперь вы хотите создать завод, чтобы получить правильную реализацию джинзона. Вы можете сделать это, потому что у джиназотора, в котором вы использовали (а) и (б) общий демонитадор, который является интерфейсом по умолчанию, созданным в (а). Таким образом, вы создаете абстрактную Facotry с таким методом, как этот: Public Abstract Clientginjector GetInjector (); Вы создаете двух детских бетонных классов, чтобы получить настольный компьютер/джинзон по умолчанию, и еще один, чтобы получить джинзотор планшета.

(d) Теперь вы настраиваете GWT.XML своего модуля, как и Google IO на YouTube, объясняет, что вы должны получить желаемую Facotry во время выполнения, используя отложенные привязки GWT для каждой из вашей фабрики джинзоторов.

(e) В вашей точке входа, что вы не должны получить джинзон, а ваша фабрика для джинзоторов, используя отложенное связывание GWT. Вы называете абстрактный метод, который возвращает клиентский Ginector, ваш набор.

(f) Эпический провал в конце. Guice не позволит вам связывать два раза одну и ту же ключ (класс плюс аннотация), даже если вы будете использовать разные форсунки (один для настольного компьютера и один для планшета). Кажется, что ключевые обязательные определения являются глобальными, как только у вас есть два модуля, переопределяющие одни и те же ключи, это конец приключения.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top