它表明不可能创建对象,因为未定义成员wsClient:WSClient,这是做什么用的
class ShoppingCartLoader extends LagomApplicationLoader{
override def load(context: LagomApplicationContext): LagomApplication = {
//Commenting AhcWSComponents is giving error here
new ShoppingCartApplication(context) {
override def serviceLocator: ServiceLocator = NoServiceLocator
}
}
}
abstract class ShoppingCartApplication(context: LagomApplicationContext)
extends LagomApplication(context)
/*with AhcWSComponents*/{
override lazy val lagomServer = serverFor[ShoppingCartService](wire[ShoppingCartImpl])
}
进入AhcWSComponents内部,它具有:
lazy val wsClient: WSClient = {
implicit val mat = materializer
implicit val ec = executionContext
val asyncHttpClient = new AsyncHttpClientProvider(environment, configuration, applicationLifecycle).get
new AhcWSClientProvider(asyncHttpClient).get
}
如果需要,为什么它不包含在LagomApplication
本身中
答案 0 :(得分:1)
LagomApplication
必须具有wsClient
,以便具有用于向外部服务发出HTTP请求的统一接口。包含基于AsyncHttpClient的实现(通过AhcWSComponents
拉入),但是只要满足合同,就可以使用其他实现完全可以。因此,通过混入AhcWSComponents
,可以明确决定使用包含的实现。
当需要为依赖外部服务请求编写功能的测试编写代码时,就会产生此要求的一个好处:您可以拥有一个模拟外部服务并在所有测试中使用该实现的实现,而不必在多个套件中设置相同的模拟。但是,要利用这一点,您不想在抽象类级别混入实现:
class ShoppingCartLoader extends LagomApplicationLoader {
override def load(context: LagomApplicationContext): LagomApplication = {
// as above until
new ShoppingCartApplication(context) with AhcWSComponents {
override def serviceLocator: ServiceLocator = NoServiceLocator
}
}
}
// now you don't need `with AhcWSComponents` on the abstract class
然后在测试中,当您需要LagomApplication
时:
new ShoppingCartApplication(context) {
override def wsClient: WSClient = ??? // mock implementation here
}