Используйте gwt ui-binding вместе с google-gin

Есть ли способ использовать внедрение зависимостей в виджет, созданный с помощью привязки пользовательского интерфейса?

Предположим, у меня есть простой виджет (в пакете com.example.client.ui.widget):

public class Foo extends Composite {

    private final EventBus eventBus;

    @Inject
    public Foo(final EventBus eventBus) {
        this.eventBus = eventBus;
        // create ui
    }
}

а затем у меня есть представление, определенное через привязку пользовательского интерфейса, которое использует этот виджет. например:

<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'
    xmlns:g='urn:import:com.google.gwt.user.client.ui'
    xmlns:app='urn:import:com.example.client.ui.widget'>

    <g:HorizontalPanel>
        <app:Foo/>
    </g:HorizontalPanel>
</ui:UiBinder>

Выполнение этого так не работает из-за ограничения конструктора без аргументов для виджетов, которые используются в привязке пользовательского интерфейса. Но было бы неплохо, если бы компилятор GWT просто использовал GIN при наличии аннотации @Inject? Или это можно сделать как-то иначе? Возможно, я полностью упускаю концепцию GIN и GWT, если это так, любые подсказки очень ценятся.

Заранее спасибо, Маркус


person schub    schedule 04.01.2012    source источник
comment
Понятно, что представление, объявленное через ui-binding, само привязывается в конфиге gin.   -  person schub    schedule 04.01.2012
comment
См. code.google.com/p/google-web. -toolkit/issues/detail?id=6151   -  person Thomas Broyer    schedule 05.01.2012


Ответы (1)


если вам нужна инъекция зависимостей для виджетов, вы делаете что-то не так.

НО

Можно использовать GIN для внедрения некоторых вещей в ваши виджеты.

Подумайте о следующем: GIN — это автономная среда внедрения зависимостей, вы просто спрашиваете, что вам нужно, GIN создаст bean-компонент с разрешенными зависимостями. Инъекция будет выполнена только в том случае, если объект был получен из экземпляра Ginjector. UI binder — это фреймворк для декларативного пользовательского интерфейса, он создает виджеты на основе вашего XML (и делает кучу других вещей, но пока мы можем их игнорировать).

Поэтому, если мы хотим использовать GIN для внедрения зависимостей в виджет, это означает, что виджет должен быть создан GIN, а не UiBinder. UiBinder должен будет использовать экземпляр, предоставленный GIN. Является ли это возможным? Да, это позволяет UiBinder:

используя аннотацию @UiField (при условии = true) в поле виджета

or

с помощью @UiFactory

Итак, что вам нужно сделать, это создать привязку для виджета в вашем GinModule, получить его экземпляр через Ginjector или внедрить поставщика для виджета, после чего вы можете передать экземпляр виджета в UiBinder через @UiField (при условии = true) или @UiFactory.

person jusio    schedule 04.01.2012
comment
Привет Джусио, спасибо за ваш ответ. UiFactory был именно тем, что я искал :) Представление теперь внедряет Provider‹Foo›. Затем я аннотировал метод с помощью UiFactory, который предоставляет экземпляр Foo с использованием поставщика this. Но, судя по вашему первому предложению, почему такой плохой дизайн? Что можно сделать лучше, чтобы отделить виджеты, но при этом иметь EventBus внутри этих виджетов, чтобы реагировать на взаимодействие с пользователем? - person schub; 05.01.2012
comment
Виджет обычно низкоуровневый, очень универсальная вещь и обычно для того, чтобы создать виджет, нужно только настроить только действительно необходимые вещи. Я действительно не могу себе представить, почему кнопке или CellList может понадобиться инъекция зависимостей или, например, EventBus. Они должны быть многоразовыми. И всеми их зависимостями надо управлять не внедрением зависимостей, а например View. По сути, внедрение зависимостей fwk следует использовать не для всего вашего кода, а для некоторых высокоуровневых абстракций (например, представлений, презентаторов, служб и т. д.). PS: это мое личное мнение, многие люди могут не согласиться. - person jusio; 05.01.2012
comment
Я согласен с общей точкой зрения виджета, в моем случае, хотя технически это виджет (поскольку он расширяет Composite), его следует рассматривать как повторно используемый компонент в конкретном контексте приложения (довольно сложный виджет, а не просто контекст). независимое управление пользовательским интерфейсом) с элементами взаимодействия с пользователем, поэтому ему нужен EventBus и т. д. Но, как вы сказали, мнения могут отличаться, спасибо за обсуждение :) - person schub; 05.01.2012
comment
Я не могу представить свои приложения без средства ClientBundle - он обрабатывает для меня весь CSS очень строго и имеет максимальный уровень защиты от ошибок: сбой во время компиляции. Пользовательские виджеты получают свои стили из связанных экземпляров ClientBundle. Смешивание GWT.create() и @Inject — плохая практика, поэтому я предпочитаю внедрять все, включая мой ClientBundle. Поэтому я создаю соответствующую одноэлементную привязку в соответствующем модуле конфигурации gin. Эта простая логика не оставляет места для сомнений, являются ли виджеты объектами инъекций или нет. Они есть. - person vitrums; 26.10.2016