/ / Play Framework 2.5.x: Injetar Ambiente em um Módulo - scala, injeção de dependência, guice, playframework-2.5

Play Framework 2.5.x: Injetar Ambiente em um Módulo - scala, dependency-injection, guice, playframework-2.5

O aplicativo de reprodução contém um módulo personalizado queinicializa DB / Tables durante o início do aplicativo. A partir da v2.5.x, o modo de aplicativo (prod, test, dev) precisa ser injetado, em vez de usar Current. Tentei aplicar os seguintes parâmetros de injeção no código do módulo, mas vi erros de compilação.

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

Existe uma maneira prescrita de procurar Ambiente / Modo durante a inicialização do módulo no Play 2.5.x (Scala)?

Respostas:

2 para resposta № 1

Vou reescrever seu código para remover uma pequena confusão possível aqui. Este é exatamente o seu código com uma pequena renomeação dos parâmetros de tipo:

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

Eu renomei os parâmetros de tipo para evitar confusão com play.api.Environment. Eu tenho o sentimento de que isso não é o que você quer, já que MyInitClass não recebe ativamente play.api.Environment qualquer lugar.

Se você quer fazer alguma inicialização, por que não ir com algo mais simples e direto assim:

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

Editar:

Uma maneira mais idiomática e recomendada de substituir GlobalSettings.onStart é descrito nos docs:

GlobalSettings.beforeStart e GlobalSettings.onStart: Tudo o que precisa acontecer no arranquedeve agora estar acontecendo no construtor de uma classe de injeção de dependência. Uma classe executará sua inicialização quando a estrutura de injeção de dependência a carregar. Se você precisa de uma inicialização rápida (porque você precisa executar algum código antes a aplicação é realmente iniciada), definir uma ligação ansiosa.

Então, podemos reescrever seu código para algo assim:

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

Observe como eu removi o trait já que não está adicionando nenhum valor aqui.