如何使用Scala和Play 2.5.x在对象中获取application.conf变量?

时间:2016-07-27 12:04:41

标签: scala playframework dependency-injection guice

我曾经使用application.conf在Play 2.4.x中获取Play.current.configuration.getString('NAME_HERE')变量,并且它在类,对象和伴随对象中也运行良好。

现在,我在一个新项目中使用Play 2.5.4和Scala,我不会使用这个Play.current,因为它已被弃用,但有另一种选择使用DI,像这样:

class HomeController @Inject() (configuration: play.api.Configuration) extends Controller {
  def config = Action {
    Ok(configuration.underlying.getString("db.driver"))
  }
}

这个DI注入就像课堂上的魅力一样,但在这个项目中,我需要在对象中获取变量db.driver?据我所知,对象我不能使用DI。

也许使用Guice有帮助吗?

3 个答案:

答案 0 :(得分:1)

您可以使用@Singleton带注释的类代替object

trait Foo {}

@Singleton
class FooImpl @Inject()(configuration: play.api.Configuration)) extends Foo {
  //do whatever you want
}

@Singleton使该类成为单例。感觉有点尴尬,因为Scala本身具有语法object来创建单例,但这是DI最简单且可能是最佳解决方案。

您也可以像下面的代码一样热切地创建单身。

bind(classOf[Foo]).to(classOf[FooImpl])asEagerSingleton()

有关详情,请参阅Google Guice WikiPlayframework site

修改

你如何称呼它与你在Playframework2.5中的DI方式完全相同。

class BarController @Inject()(foo: Foo) extends Controller {
  //Do whatever you want with Foo
}

每次你进行DI时,Guice基本上都会生成新实例。一旦你放置@Singleton,Guice只会使用一个实例。

DI用于反高耦合。所以当你想使用你从另一个类定义的类时,你需要DI,否则这些类是高度耦合的,这最终会使你的单元测试编码变得更加困难。

仅供参考,您可以使用此技术在Play之外使用它们。

Create an Instance of class which does DI via Playframework Guice Independently in Scala

答案 1 :(得分:0)

你可以做到

Play.current.configuration

然而,Play 2.6可能不再可能。

但是,理想情况下,您可以将配置作为参数传递给对象的该方法,或者使用类而不是对象。

我最近需要做些什么才能从对象迁移到班级':

class MyComponent @Inject() (config: Configuration) {
  // here goes everything nice
  def doStuff = ???
}

object MyComponent {
  @deprecated("Inject MyComponent")
  def doStuff = {
    val instance = Play.current.injector.instanceOf[MyComponent]
    instance.doStuff
  }
}

这样,您的方法的所有用户都可以慢慢迁移到使用类,而不会破坏现有代码。

答案 2 :(得分:0)

你试过吗

import com.typesafe.config.ConfigFactory
val myConfig = ConfigFactory.load().getString("myConfig.key")

以上方法不要求您将对象转换为单例类。