Инъекция зависимостей playFramework в объект scala с использованием черт MacWire не удалась

Допустим, в моем проекте есть куча автомобильных объектов, например:

object Porsche extends Car {
   override def start() {...}
   override def canStart(fuelInLitr: Int) = fuelInLitr > 5

   override val fuelInLitr = 45
   override val carId = 1234567
}

Я расширяю автомобиль, который является отличительной чертой для определения структуры автомобиля:

trait Car {
  def start(): Unit
  val canStart(fuel: Double): Boolean
  val fuelInLitr: Int
  val carId: Int
}

Теперь в start() Я хочу использовать какой-нибудь API-сервис, который даст мне ключ от машины на основе его идентификатора, чтобы я не смог завести машину.

Итак, у меня есть это CarApiService:

class CarApiService (wsClient: WSClient, configuration: Configuration) {

  implicit val formats: Formats = DefaultFormats

  def getCarkey(carId: String): Future[Option[CarKey]] = {

    val carInfoServiceApi = s"${configuration.get[String]("carsdb.carsInfo")}?carId=$carId"

    wsClient.url(carInfoServiceApi).withHttpHeaders(("Content-Type", "application/json")).get.map { response =>
      response.status match {
        case Status.OK => Some(parse(response.body).extract[CarKey])
        case Status.NO_CONTENT => None
        case _ => throw new Exception(s"carsdb failed to perform operation with status: ${response.status}, and body: ${response.body}")
      }
    }
  }
}

Я хочу иметь возможность использовать getCarkey() в моих автомобильных объектах, поэтому я создал CarsApiServicesModule, который даст мне доступ к carApiService и я могу использовать его методы:

trait CarsApiServicesModule {

  /// this supply the carApiService its confuguration dependancy 
  lazy val configuration: Config = ConfigFactory.load()
  lazy val conf: Configuration = wire[Configuration]

  /// this supply the carApiService its WSClient dependancy 
  lazy val wsc: WSClient = wire[WSClient]

  lazy val carApiService: CarApiService = wire[CarApiService]
}

и теперь я хочу добавить микс этой черты в мой автомобильный объект следующим образом:

object Porsche extends Car with CarsApiServicesModule {
    // here I want to use myApiService
    // for example: carApiService.getCarkey(carId)...
}

но при компиляции я получаю эту ошибку:

кто-нибудь знает в чем проблема?

также, имеет ли этот дизайн смысл?

1 ответ

Решение

Вы должны иметь в виду, что wire это просто вспомогательный макрос, который пытается сгенерировать новый код создания экземпляра: на самом деле он довольно тупой. Здесь он попытается создать новый экземпляр WSClient,

Однако не все объекты могут быть созданы с использованием простого new call - иногда вам нужно вызвать "фабричный" метод.

В этом случае, если вы посмотрите на readme на GitHub, вы увидите это для создания экземпляра WSClientвам нужно создать его через StandaloneAhcWSClient() объект.

Так что в этом случае wire вам не поможет - вам нужно просто написать код инициализации вручную. К счастью, он не слишком большой.

Другие вопросы по тегам