/ / Play Framework 2.5.x: Środowisko wstrzyknięcia w module - scala, iniekcja zależności, guice, playframework-2.5

Zagraj w Framework 2.5.x: Inject Environment in a Module - scala, iniekcja zależności, guice, playframework-2.5

Aplikacja Play zawiera niestandardowy moduł, któryinicjuje DB / Tables podczas uruchamiania aplikacji. Począwszy od wersji 2.5.x, tryb aplikacji (prod, test, dev) musi być wtryśnięty, zamiast używać Current. Próbowałem zastosować następujące parametry iniekcji w kodzie modułu, ale zauważyłem błędy kompilacji.

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()
}
}

Czy istnieje określony sposób wyszukiwania środowiska / trybu podczas inicjalizacji modułu w Play 2.5.x (Scala)?

Odpowiedzi:

2 dla odpowiedzi № 1

Przepiszę twój kod, aby usunąć tutaj małe możliwe zamieszanie. To jest dokładnie twój kod z niewielką zmianą parametrów typu:

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()
}
}

Zmieniłem nazwę parametrów, aby uniknąć pomyłki play.api.Environment. Mam wycinkę, że to nie jest to, czego chcesz, odkąd MyInitClass nie aktywnie otrzymuje play.api.Environment gdziekolwiek.

Jeśli chcesz przeprowadzić inicjalizację, możesz skorzystać z czegoś prostszego i bardziej bezpośredniego:

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
}
}
}

Edytować:

Bardziej idiomatyczny i zalecany sposób wymiany GlobalSettings.onStart jest opisane na dokumentach:

GlobalSettings.beforeStart i GlobalSettings.onStart: Wszystko, co musi się wydarzyć po uruchomieniupowinno się teraz dziać w konstruktorze klasy, w której wstrzyknięta jest zależność. Klasa wykona swoją inicjalizację, gdy struktura wstawiania zależności załaduje ją. Jeśli potrzebujesz szybkiej inicjalizacji (ponieważ musisz wykonać jakiś kod przed aplikacja jest faktycznie uruchomiona), Zdecyduj się na agresywne wiązanie.

Możemy więc przepisać twój kod tak, aby wyglądał następująco:

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()
}
}

Zauważ, jak usunąłem trait ponieważ nie dodaje tutaj żadnej wartości.