按环境分离的Scala服务(服务定位器?)

时间:2014-05-30 10:34:24

标签: scala dependency-injection production-environment service-locator

我的Scala应用程序支持2种环境:TEST和PROD。不同之处在于使用服务。例如,生产Emailer实际上发送一封电子邮件,测试Emailer是相当存根或模拟。 环境由参数配置。 你如何实现这种按环境分离的服务?你更喜欢像Guice这样的DI解决方案吗?

1 个答案:

答案 0 :(得分:2)

除了Guice之外,如果需要,还可以继续使用本机Scala蛋糕模式依赖注入。

// MyService.scala
trait MyService {
   this: Emailer =>   // Cake pattern: this must be instatiated with an Emailer trait

   def doSomething() {
      //...
      this.email(...)
      //...
   }
}

// Somewhere else
trait Emailer { def email(args: String): Unit }
trait MockEmailer { override def email(args: String) = println("Email was sent!") }
trait RealEmailer { override def email(args: String) = actuallySendAnEmail(args) }

// Application.scala    
sealed trait Environment
case object Test extends Environment
case object Prod extends Environment

object Application {
   private var _environment: Environment = Test // Choose default
   def environment = _environment

   def main(args: Array[String) {
       // Determine environment at startup
       if(args.contains("PROD") {
         _environment = Prod
       } else {
         _environment = Test
       }
       // ...
   }
}

// Configuration.scala
val myService = Application.environment match {
   case Test => new MyService with MockEmailer
   case Prod => new MyService with RealEmailer
}

自己编写这些内容需要花费一些,但它并不需要任何单独的依赖注入框架及其自己的注释动词。此外,您不会遇到运行时依赖注入错误 - Scala编译器保证这将起作用。