在Scala函数中创建Guice依赖项注入绑定

时间:2019-01-11 08:45:30

标签: scala dependency-injection playframework guice

我想绑定某个类,让其injected或它的实际实现real或其mock来命名。

还应该发生副作用,因此最好使用函数来封装这项工作。

在功能之外执行此操作是已知的。但这还需要对副作用进行多次编码

我正在寻找的功能可以概括为这种方式(没有可行的方法!)

  private def bindMocksOptional(configSettingKey: String, injected: Class[_], real: Class[_] , mock: Class[_]) {
    configuration.getOptional[Boolean](configSettingKey) match {
      case Some(true) => {
        bind(injected).to(mock)
        val message = s"Using a mock (${mock.getCanonicalName})for ${injected.getCanonicalName}"
        Logger.warn(message)
        println(Console.MAGENTA + message)
      }
      case _ => bind(injected).to(real)
    }
  }

该函数应将概述的类型作为参数,查找一些配置设置,并基于这些设置绑定到模拟或实际实现。

1 个答案:

答案 0 :(得分:0)

您可以使用Provider

import com.google.inject.{AbstractModule, Guice, Inject, Provider}

class Configuration {
  def getOptional[T](key: String): Option[T] = None
}

trait DatabaseClient

class DatabaseClientMock extends DatabaseClient
class DatabaseClientReal extends DatabaseClient

// ---

// 1. Define Guice Provider:
class DatabaseClientGuiceProvide @Inject()(configuration: Configuration)
    extends Provider[DatabaseClient] {
  override def get(): DatabaseClient = {
    configuration.getOptional[Boolean]("mock") match {
      case Some(true) =>
        println("used mock")
        new DatabaseClientMock
      case _ =>
        println("used real")
        new DatabaseClientReal
    }
  }
}

class MainModule extends AbstractModule {
  override def configure(): Unit = {
    // 2. Bind dependencies of provider
    bind(classOf[Configuration]).toInstance(new Configuration)

    // 3. Bind provider
    bind(classOf[DatabaseClient])
      .toProvider(classOf[DatabaseClientGuiceProvide])
  }
}


// 4. Test it:
object GuiceMain extends App {
  val module = Guice.createInjector(new MainModule)

  println(module.getInstance(classOf[DatabaseClient]))
}