/ / Play Framework 2.5.x: Ін'єкційна середовище в модулі - scala, injection-dependency, guice, playframework-2.5

Play Framework 2.5.x: Ін'єкційна середовище в модулі - scala, dependency-injection, guice, playframework-2.5

Програма для відтворення містить спеціальний модуль дляініціює DB / Tables під час запуску додатка. Починаючи з v2.5.x, режим застосування (prod, test, dev) потрібно вводити, а не використовувати поточний. Я намагався застосувати наступні параметри вводу в модулі, але побачив помилки компіляції.

trait MyInit[Environment] {
val env: Environment
}

class MyInitClass[Environment] @Inject() (
val env: Environment
) extends MyInit[Environment] {
initializeDB()

def initializeDB() = {
Logger.info("MyINIT: Creating database...")
MyDBService.createDatabase()
Logger.info("MyINIT: Creating tables...")
MyDBService.createTables()
}
}

class MyModule(environment: Environment,
configuration: Configuration) extends AbstractModule with ScalaModule {
def configure() = {
bind[MyInit[Environment]].to[MyInitClass[Environment]].asEagerSingleton()
}
}

Чи передбачений спосіб перегляду середовища / режиму під час ініціалізації модуля в Play 2.5.x (Scala)?

Відповіді:

2 для відповіді № 1

Я перепишу ваш код, щоб видалити невелику можливу плутанину тут. Це саме ваш код з невеликим перейменуванням параметрів типу:

import javax.inject.Inject
import play.api.Logger
import play.api.Environment
import play.api.Configuration
import com.google.inject.AbstractModule

trait MyInit[T] {
val env: T
}

class MyInitClass[T] @Inject() (val env: T) extends MyInit[T] {
initializeDB()

def initializeDB() = {
Logger.info("MyINIT: Creating database...")
MyDBService.createDatabase()
Logger.info("MyINIT: Creating tables...")
MyDBService.createTables()
}
}

Я перейменував параметри типу, щоб уникнути плутанини з play.api.Environment. У мене є рубка, що це не те, що ви хочете, оскільки MyInitClass не активно отримує play.api.Environment де завгодно

Якщо ви хочете зробити деяку ініціалізацію, то чому б не йти з чимось більш простим і прямим, як це:

import com.google.inject.AbstractModule
import play.api.{Configuration, Environment, Mode}

class DatabaseInitializerModule(
environment: Environment,
configuration: Configuration
) extends AbstractModule {

def configure() = {
environment.mode match {
case Mode.Dev =>
// Start dev database
case Mode.Test =>
// Start test database
case Mode.Prod =>
// Start prod database
}
}
}

Редагувати:

Більш ідіоматичний і рекомендований спосіб заміни GlobalSettings.onStart є описано в документах:

GlobalSettings.beforeStart і GlobalSettings.onStart: Все, що має відбутися при запускутепер має відбуватися в конструкторі класу, що вводиться залежністю. Клас виконає його ініціалізацію, коли система завантаження залежностей завантажує її. Якщо вам потрібна ініціалізація (тому що вам потрібно виконати деякий код раніше програма фактично запущена), визначте бажаючий зв'язок.

Отже, ми можемо переписати ваш код на щось подібне:

import javax.inject.Inject

import play.api.{Environment, Mode}
import com.google.inject.AbstractModule

class DatabaseInitializer @Inject()(environment: Environment) {
environment.mode match {
case Mode.Dev =>
// Start dev database
case Mode.Test =>
// Start test database
case Mode.Prod =>
// Start prod database
}
}

class DatabaseInitializerModule extends AbstractModule {
override def configure() = {
bind(classOf[DatabaseInitializer]).asEagerSingleton()
}
}

Зверніть увагу, як я вилучив trait тому що тут не додають ніякого значення.