如何覆盖子类中的macwire注入

时间:2017-12-21 16:49:05

标签: scala dependency-injection playframework subclass macwire

Play网络框架允许注入“过滤器”列表,对请求进行常规处理(gzip,cors,logging等)

package play.api

trait BuiltInComponents {
  ...
  lazy val httpFilters: Seq[EssentialFilter] = Nil
  <stuff that uses httpFilters>
  ...
}

我希望有一组共同的过滤器(和其他东西)。

package example

import play.api.BuildInComponents

trait MyCommonComponents extends BuiltInComponents {
    ...
    override lazy val filters = Seq(
      wire[Filter1],
      wire[Filter2],
      wire[Filter3]
    )
    ...
}

子类可以使用

package example.foo

import example.MyCommonComponents

trait MyFooComponents extends MyCommonComponents {
    ...
}

或者通过子类添加

package example.bar

import example.MyCommonComponents

trait MyBarComponents extends MyCommonComponents {
    ...
    override lazy val filters = super.filters :+ wire[Filter4]
    ...
}

我尝试过的事情

  1. 上面的代码。不能将super与lazy val一起使用。
  2. httpFilters更改为def。由于BuiltInComponents
  3. ,需要是一个稳定的值
  4. 添加lazy val httpFilters = filtersdef filters: Seq[EssentialFilter] = ...,然后根据需要覆盖filters。 Macwire抱怨模棱两可的类型。
  5. 如何实现可选的附加过滤器列表?

1 个答案:

答案 0 :(得分:0)

我可能没有得到你的情景,但简单的

有什么问题
import com.softwaremill.macwire._
import play.api.BuiltInComponents
import play.api.mvc.{EssentialAction, EssentialFilter}

class Filter1 extends EssentialFilter {
  override def apply(next: EssentialAction) = next
}

class Filter2 extends EssentialFilter {
  override def apply(next: EssentialAction) = next
}

class Filter3 extends EssentialFilter {
  override def apply(next: EssentialAction) = next
}

trait MyCommonComponents extends BuiltInComponents {

  protected lazy val baseFilters: Seq[EssentialFilter] = Seq(
    wire[Filter1],
    wire[Filter2],
  )

  override def httpFilters = baseFilters
}


trait MyFooComponents extends MyCommonComponents {

  protected lazy val fooFilters = baseFilters :+ wire[Filter3]

  override def httpFilters = fooFilters
}

或者

trait MyBarComponents extends MyCommonComponents {

  private lazy val barFilters = Seq[EssentialFilter](wire[Filter3])

  override def httpFilters = super.httpFilters ++ barFilters
}

为什么要覆盖您的lazy val而不是基本httpFilters,而这些基本<div id="content"> <p> Hello this is <ul> <li>**{I CLICK HERE}**A test<p> and some more</p></li> </ul> Lorem ipsum </p> </div> 似乎完全被设计为被覆盖。