Play Framework 2.5.x:在模块中注入环境

时间:2016-06-06 01:20:03

标签: scala dependency-injection guice playframework-2.5

Play app包含一个自定义模块,可在应用启动期间初始化DB / Tables。 从v2.5.x开始,需要注入应用程序模式(prod,test,dev)而不是使用Current。我试图在模块代码中应用以下注入参数,但看到了编译错误。

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)模块初始化期间是否有规定的查找环境/模式的方法?

1 个答案:

答案 0 :(得分:2)

我会重写你的代码,以消除这里可能出现的小混乱。这正是您的代码,它具有类型参数的小重命名:

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的更惯用且推荐的方式是described at the docs

  

GlobalSettings.beforeStartGlobalSettings.onStart:启动时需要发生的任何事情现在都应该发生在依赖注入类的构造函数中。当依赖注入框架加载它时,类将执行其初始化。如果您需要急切初始化(因为您需要在实际启动应用程序之前执行一些代码),define an eager binding

因此,我们可以将您的代码重写为:

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,因为此处未添加任何值。