Создать привязку внедрения зависимостей Guice в функции Scala - PullRequest
0 голосов
/ 11 января 2019

Я хочу связать определенный класс, давайте назовем его 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 голосов
/ 11 января 2019

Вы можете использовать Провайдер :

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

...