Примеры использования для использования инъекции зависимостей с помощью платформы воспроизведения

Я большой поклонник Injection Dependency и Play Framework, но мне трудно понять, как эти два могут быть использованы вместе.

Существуют модули для Spring и Guice, но способ, которым работает Play, усложняет мне, как DI может быть полезен за некоторыми довольно простыми случаями.

Хорошим примером этого является то, что Play ожидает, что работа JPA будет выполняться статическими методами, связанными с данным объектом:

@Entity
Person extends Model {
    public static void delete(long id) {
        em().find(id).remove();
    }

    //etc
}

Таким образом, не нужно вводить PersonManager в контроллеры так, как это возможно для приложения Spring J2EE. Вместо этого контроллер просто вызывает Person.delete(x).

Очевидно, что DI полезен, когда есть интерфейсы с внешними системами, поскольку конкретную реализацию можно издеваться над тестированием и т.д., но я не вижу большой пользы для автономного приложения Play.

Есть ли у кого-нибудь хорошие примеры? Кто-нибудь использует его, чтобы внедрить класс Manager -style в Controller, чтобы можно было выполнить несколько операций в рамках одной транзакции, например?

Ответ 1

Я считаю, что из этого предложения вы написали:

"Есть ли у кого-нибудь хорошие примеры? Кто-нибудь использует его для ввода класса стиля менеджера в контроллеры, чтобы, например, выполнить несколько операций в рамках одной транзакции?"

перед тем как ответить на вопрос DI, я должен кое-что отметить: транзакции автоматически управляются Play. Если вы проверите документацию , вы увидите, что транзакция автоматически создается в начале запроса и завершается в конце. Вы можете откатить его обратно через JPA или он будет откат, если будет создано исключение.

Я упоминаю об этом, потому что из формулировки вашего предложения я не уверен, знаете ли вы об этом.

Теперь, на самом DI, в моем (не столь обширном) опыте с DI, я видел, что он использовался главным образом для:

  • Загрузите ORM (Hibernate) factory/manager
  • Загружать классы обслуживания /DAO в другой класс для работы с ними.

Конечно, есть больше сценариев, но они, вероятно, покрывают большую часть реального использования. Сейчас:

  • Первый не имеет значения для Play, так как вы автоматически получаете доступ к объекту и транзакции JPA.
  • Второй тоже не имеет значения, поскольку вы в основном работаете со статическими методами в контроллерах. У вас могут быть некоторые вспомогательные классы, которые необходимо создать, и некоторые из них могут даже принадлежать иерархии (общий интерфейс), поэтому DI был бы полезен. Но вы могли бы также создать свой выигранный класс factory и избавиться от банок DI.

Здесь есть еще один вопрос: я не уверен в Guice, но Spring - это не только DI, но и предоставляет множество дополнительных функций, которые зависят от модуля DI. Возможно, вы не хотите использовать DI в Play, но вы хотите использовать инструменты Spring, и они будут использовать DI, хотя и косвенно (через конфигурацию xml).

Ответ 2

Проблема в моем скромном мнении о статическом подходе к инициализации Play! заключается в том, что он делает тестирование сложнее. После того, как вы подходите к проблеме HTTP с объектной ориентацией со статическими членами и объектами, которые содержат данные HTTP-запроса (запрос и ответ), вы делаете сделку с необходимостью создавать новые экземпляры для каждого запроса, чтобы сделать ваши объекты слабо связанными с остальными ваших классов проекта.

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

Я считаю, что, может быть, сочетание двух подходов было бы лучше, если бы один синглтон каждого контроллера дал бы одни и те же характеристики полного статического класса и позволил бы впрыскивать некоторые виды объектов. Но не объекты с областью запроса или сеанса, как только контроллер должен будет создать каждый новый запрос. Кроме того, это улучшило бы тестируемость путем инвертирования контроля инъекции зависимостей, что позволило бы использовать произвольные точки инъекции.

Зависимости будут впрыскиваться контейнером или тестом, вероятно, используя макеты для тяжелого материала, который, скорее всего, уже был протестирован раньше.

С моей точки зрения, эта статическая модель отталкивает разработчика от тестирования контроллеров, потому что расширение FunctionalTest запускает сервер приложений, цены на тяжелые объекты, такие как репозитории, службы, сканеры, http-клиенты и т.д. Я не хочу ждать много объектов, которые нужно загружать, чтобы проверить, был ли какой-то код выполнен на контроллере, тесты должны быть быстрыми и понятными, чтобы сделать разработчики любят их в качестве своего помощника по программированию/руководства.

Ответ 3

DI не является окончательным решением для использования везде... Не используйте DI только потому, что у вас есть это в ваших руках... В игре вам не нужно DI для разработки контроллеров/моделей и т.д.... но иногда это может быть приятный дизайн: IMO, вы можете использовать его, если у вас есть сервис с хорошо знакомым интерфейсом, но вы хотели бы развивать эту услугу за пределами Play и тестировать ее вне игры и даже тестировать свой игровой проект с помощью только фиктивного сервиса чтобы не зависеть от полной реализации сервиса. Поэтому DI может быть интересным: вы произвольно подключаете службу к игре. Фактически, это оригинальный вариант использования DI afaik...

Ответ 4

Я только что написал сообщение в блоге о настройке приложения Play Framework с Google Guice. http://geeks.aretotally.in/dependency-injection-with-play-framework-and-google-guice

Я вижу некоторые преимущества, особенно если для компонента вашего приложения требуется другое поведение, основанное на определенном контексте или что-то в этом роде. Но я считаю, что люди должны быть избирательными в отношении того, что входит в контекст DI.

Ответ 5

Это снова показывает, что вы должны использовать инъекции зависимостей, если у вас действительно есть преимущество. Если у вас сложные услуги, это полезно, но во многих случаях это не так. Прочтите главу о моделях в play-documentation.

Итак, дадим вам пример, где вы можете использовать DI с игрой. Возможно, вы должны сделать сложный расчет или создать pdf файл с движком отчета. Там я думаю, что DI может быть полезен, специально для тестирования. Там я думаю, что guice-module и spring -модуль полезны и могут вам помочь.

Нильс

Ответ 6

По состоянию на год и некоторые изменения позже, игра 2.1 теперь имеет поддержку инъекции зависимостей в контроллерах. Вот их демонстрационный проект с использованием Spring 3, который четко излагает это.

Изменить: здесь другой пример с использованием Guice и Scala, если это ваш яд.