简体   繁体   中英

Fail to wire play dependancies with Macwire

i have a api service class that is dependent on play's Configuration and WSClient instancees.

and I dont want to use @Inject() anotation cause I want to use compile-time injection with Macwire so what i did is this:

// this is a trait that here im wiring all the dependencies that my api service needs
trait ApiDependencies {

  lazy val conf: Configuration = wire[Configuration]
  lazy val wsc: WSClient = wire[WSClient]

}


// this is the api service

class ApiService extends ApiDependencies {

  def getInfo (id: String): Future[Option[Info]] = {
    wsc.url("...").withHttpHeaders(("Content-Type", "application/json")).get.map { response =>
      response.status match {
        case Status.OK => ...
        case Status.NO_CONTENT => ...
        case _ => throw new Exception()
      }
    }
  }
}

but I get a compiler error:

Error: Cannot find a value of type: [com.typesafe.config.Config]
lazy val conf: Configuration = wire[Configuration]

Error: Cannot find a public constructor nor a companion object for [play.api.libs.ws.WSClient] lazy val wsc: WSClient = wire[WSClient]

does someone knows how can I solve this issue...? and why is it happening :/

thanks!

Configuration is a playframework Configuration, which internally uses Typesafe's Config library . Quoting Playframework docs :

The configuration file used by Play is based on the Typesafe config library

The exception you're getting tells you exactly this - macwire is unable to create an instance of Configuration as there are no Config instance in scope.

To fix it, you obviously need to provide such instace. Simplest way to do so would probably look like this:

import com.typesafe.config.{Config, ConfigFactory}
trait ApiDependencies {
    lazy val configuration: Config = ConfigFactory.load()
    lazy val conf: Configuration = wire[Configuration]
}

Note that ConfigFactory.Load() basically uses default configuration file ( application.conf ) and it does take into account configuration overriding techniques described in Play's Configuration docs , as it is actually provided by typesafe config library (from Typesafe Config GitHub readme):

users can override the config with Java system properties, java -Dmyapp.foo.bar=10


Regarding WSClient : this is due to the fact that WSClient is not a class, but a trait . You need to wire actual implementation, ie NingWSClient , like this:

trait ApiDependencies {
  lazy val conf: Configuration = wire[Configuration]
  lazy val wsc: WSClient = wire[NingWSClient]
}

See WSClient scaladoc for list of implementing classes (under "All Known Implementing Classes") - by the time of writing there are only NingWSClient and AhcWSClient . Which one is better is a different (and potentially opinion-based question).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM