Инъекция зависимостей 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
вам не поможет - вам нужно просто написать код инициализации вручную. К счастью, он не слишком большой.