Как подключиться к жизненному циклу игры с помощью модуля вместо плагина?

Я вижу, что класс Plugin теперь устарел (начиная с версии 2.4.x игры)... В документации API сказано, что вместо этого я должен использовать модули... так что это мой вопрос. Как написать модуль и как подключить этот модуль к жизненному циклу воспроизведения основного приложения?


person Alejandro Navas    schedule 25.07.2015    source источник


Ответы (1)


Вы не указываете, какой язык вы используете, поэтому я быстро расскажу об обоих. Я основываю оба ответа на следующих репозиториях:

Ява

  1. Пишите свою функциональность так, как хотите — нет конкретных классов для расширения. Если у вас есть зависимости от компонентов Play, таких как Configuration, вы должны внедрить их.

    @Singleton
    public class MyModuleCode {
    
        private final boolean enableWidgets;
    
        @javax.inject.Inject
        public MyModuleCode(final Configuration configuration) {
            this.enableWidgets = configuration.getBoolean("widgets.enabled", false);
        }
    }
    

Обратите внимание, что внедрение зависимостей используется вместо статической ссылки. Также обратите внимание, что я дал этому примеру аннотацию @Singleton, но также возможно иметь, например, область действия для каждого запроса.

Дополнительные сведения см. в документах Play DI.

  1. Откройте компоненты вашего модуля. Для этого расширьте класс play.api.inject.Module и реализуйте public Seq<Binding<?>> bindings(final Environment environment, final Configuration configuration).

    package com.example.module;
    
    public class MyModule extends Module
    {
        @Override
        public Seq<Binding<?>> bindings(final Environment environment,
                                        final Configuration configuration)
        {
            return seq(bind(MyModuleCode.class).toSelf().in(Singleton.class));
        }
    }
    

Здесь вы также можете привязать реализации к интерфейсам, настроить поставщиков экземпляров и так далее.

  1. Если вы публично выпускаете модуль, давайте предположим, что вы делаете это здесь — это выходит за рамки вопроса. Предположим также, что вы добавили зависимость для модуля в любом проекте, над которым работаете.

  2. Включите модуль в application.conf.

    play {
        modules {
            enabled += com.example.module.MyModule
        }
    }
    
  3. Компоненты, представленные через ваш модуль — в этом примере всего MyModuleCode — теперь доступны для внедрения в ваши контроллеры, действия и т. д.

  4. Если вам нужен хук выключения, просто введите ApplicationLifecycle в компонент и зарегистрируйте хук; см. https://playframework.com/documentation/2.4.x/JavaDependencyInjection#Stopping/cleaning-up для получения подробной информации.

Скала

  1. Пишите свою функциональность так, как хотите — нет конкретных классов для расширения. Если у вас есть зависимости от компонентов Play, таких как CacheApi, вы должны внедрить их.

    @Singleton
    class DefaultPatternCache @Inject() (cache: CacheApi) extends PatternCache {
        override def apply(value: String): Option[Pattern] = cache.getOrElse[Option[Pattern]](key = s"Deadbolt.pattern.$value") { Some(Pattern.compile(value)) }
    }
    

Обратите внимание, что внедрение зависимостей используется вместо статической ссылки. Также обратите внимание, что я дал этому примеру аннотацию @Singleton, но также возможно иметь, например, область действия для каждого запроса.

Дополнительную информацию см. в документах Play DI.

  1. Откройте компоненты вашего модуля. Для этого расширьте класс play.api.inject.Module и реализуйте def bindings(environment: Environment, configuration: Configuration): Seq[Binding[_]].

    package com.example.module
    
    import com.example.module.cache.{DefaultPatternCache, PatternCache}
    import play.api.inject.{Binding, Module}
    import play.api.{Configuration, Environment}
    
    class MyModule extends Module {
        override def bindings(environment: Environment, configuration: Configuration): Seq[Binding[_]] = Seq(bind[PatternCache].to[DefaultPatternCache])
    }
    

Здесь вы также можете привязать реализации к трейтам, настроить поставщиков экземпляров и так далее.

  1. Если вы публично выпускаете модуль, давайте предположим, что вы делаете это здесь — это выходит за рамки вопроса. Предположим также, что вы добавили зависимость для модуля в любом проекте, над которым работаете.

  2. Включите модуль в application.conf.

    play {
        modules {
            enabled += com.example.module.MyModule
        }
    }
    
  3. Компоненты, представленные через ваш модуль — всего MyModuleCode в этом примере — теперь доступны для внедрения в ваши контроллеры, действия и т. д.

  4. Если вам нужен хук выключения, просто введите ApplicationLifecycle в компонент и зарегистрируйте хук; см. https://playframework.com/documentation/2.4.x/ScalaDependencyInjection#Stopping/cleaning-up для получения подробной информации.

Резюме

Модули больше не являются чем-то особенным — это просто способ группировки внедряемых компонентов.

person Steve Chaloner    schedule 28.07.2015
comment
Что делать, если я хочу зарегистрировать json-модуль Jackson? где мне это сделать (без глобальных настроек)? мне не нужно вводить какой-то экземпляр какого-то класса в мой код, мне просто нужно запустить какой-то код перед любым http-запросом. - person Alejandro Navas; 29.07.2015
comment
Это подробно описано в документации: playframework.com/documentation/2.4.x/JavaHttpRequestHandlers. playframework.com/documentation/2.4.x/ScalaHttpRequestHandlers - person Steve Chaloner; 29.07.2015
comment
Я имею в виду, что мне нужно сделать это до того, как произойдет какой-либо http-запрос, но только один раз, а не один запрос pero. - person Alejandro Navas; 05.09.2015
comment
Объявите класс, содержащий код, как нетерпеливый синглтон — он будет запущен один раз при запуске приложения. См. playframework.com/documentation/2.4.x/ для Детали. - person Steve Chaloner; 10.09.2015