定义依赖于隐式的抽象类或特征

时间:2012-10-18 02:50:34

标签: scala inheritance playframework-2.0 traits

我有这个游戏框架2代码(简化):

import formatters.json.IdeaTypeFormatter._

object IdeaTypes extends Controller {

  def list = Action { request =>
    Ok(toJson(IdeaType.find(request.queryString)))
  }

  def show(id: Long) = Action {
    IdeaType.findById(id).map { ideatype =>
      Ok(toJson(ideatype))
    }.getOrElse(JsonNotFound("Type of idea with id %s not found".format(id)))
  }
}

IdeaType类扩展了Entity,它的伴随对象IdeaType扩展了EntityCompanion

正如您所料,我在每个控制器中都有这种代码,因此我想将基本行为提取到特征中,如下所示:

abstract class EntityController[A<:Entity] extends Controller {
  val companion: EntityCompanion
  val name = "entity"

  def list = Action { request =>
    Ok(toJson(companion.find(request.queryString)))
  }
  def show(id: Long) = Action {
    companion.findById(id).map { entity =>
      Ok(toJson(entity))
    }.getOrElse(JsonNotFound("%s with id %s not found".format(name, id)))
  }
}

但是我收到以下错误:

[error] EntityController.scala:25: No Json deserializer found for type List[A]. 
[error] Try to implement an implicit Writes or Format for this type.
[error]     Ok(toJson(companion.find(request.queryString)))
[error]              ^
[error] EntityController.scala:34: No Json deserializer found for type A.
[error] Try to implement an implicit Writes or Format for this type.
[error]       Ok(toJson(entity))
[error]                ^

我不知道如何判断隐式Writes将由实现EntityController特征的类实现(或继承抽象类EntityController

- 编辑

到目前为止我现在这样做:

abstract class CrudController[A <: Entity](
  val model: EntityCompanion[A],
  val name: String,
  implicit val formatter: Format[A]
) extends Controller {

并像这样使用

object CrudIdeaTypes extends CrudController[IdeaType](
  model = IdeaType, 
  name = "type of idea", 
  formatter = JsonIdeaTypeFormatter
)

我无法让scala使用implicits自动选择它。我尝试使用此导入,但它无法正常工作

import formatters.json.IdeaTypeFormatter._

1 个答案:

答案 0 :(得分:7)

如果希望控制器类本身定义隐式,则只需声明抽象隐式值,并在派生类中定义它们。

abstract class EntityController[A<:Entity] extends Controller {
  protected implicit def entityWriter: Writes[A]
  protected implicit def entityListWriter: Writes[List[A]]
  ...      
}

class MyEntity extends Entity {
  ...
}

class MyEntityController extends EntityController[MyEntity] {
  protected def entityWriter: Writes[MyEntity] = ...
  protected def entityListWriter: Writes[List[MyEntity]] = ...    
}

但是,在控制器外部定义这些隐含更为实际,通常在实体的伴随对象中,以便编译器可以自动找到它们而无需导入。 然后,将隐式值传递给EntityController

的构造函数
abstract class EntityController[A<:Entity](implicit entityWriter: Writes[A], entityListWriter: Writes[List[A]] ) extends Controller {
  ...      
}

class MyEntity extends Entity {
  ...
}
object MyEntity {
  protected implicit def entityWriter: Writes[A]
  protected implicit def entityListWriter: Writes[List[A]]
}

class MyEntityController extends EntityController[MyEntity] {
  ...
}

最后注意,List [MyEntity]的隐含可能是不需要的(因此只需要明确定义MyEntity的隐式)。我没有检查过,但通常在使用这个&#34;类型模式&#34;时, 框架已经为每个List [T]定义了一个隐含的,只要有一个隐含的T。虽然我没有检查过,但可能就是这种情况。