【发布时间】:2016-06-15 01:50:02
【问题描述】:
我怎样才能通过只知道它的超类来找到正确的隐式CommandHandler 类型类?
在 MainRunner 类中,您可以看到以下代码要求我实现 AllCommandHandler 类型类,该类对所有类型进行模式匹配。有没有一种方法可以在不实现 AllCommandsHandler 的情况下为超类型 UserCommand 找到正确的类型类?
val command: UserCommand = CreateUser("userId2")
CommandHandlerRunner.processCommand(command)
我需要这个的原因是因为我的代码的某些部分得到了一个List[UserCommand],它要么来自数据库,要么在验证输入命令后生成。
我的代码
import annotation.implicitNotFound
@implicitNotFound("No member of type class CommandHandler in scope for ${C}")
trait CommandHandler[C <: UserCommand] {
def processCommand(command: C)
}
trait Command
sealed trait UserCommand
case class CreateUser(id: String) extends UserCommand
case class UpdatePassword(id: String, password: String) extends UserCommand
object CommandHandler {
implicit object CreateUserCommandHandler extends CommandHandler[CreateUser] {
override def processCommand(command: CreateUser) = println(command)
}
implicit object UpdateUserPasswordCommandHandler extends CommandHandler[UpdatePassword] {
override def processCommand(command: UpdatePassword) = println(command)
}
//I have to do this which is ugly. Is there a way I can invoke the right CommandHandler without doing the following ?
implicit object AllCommandsHandler extends CommandHandler[UserCommand] {
override def processCommand(command: UserCommand) = command match {
case command: CreateUser =>
CommandHandlerRunner.processCommand(command)
case command: UpdatePassword =>
CommandHandlerRunner.processCommand(command)
case _ =>
sys.error("CommandHandler not found.")
}
}
}
object CommandHandlerRunner {
def processCommand[C <: UserCommand](command: C)(implicit commandHandler: CommandHandler[C]) =
commandHandler.processCommand(command)
}
object MainRunner extends App {
CommandHandlerRunner.processCommand(CreateUser("userId1"))
CommandHandlerRunner.processCommand(UpdatePassword("userId1", "newPassword"))
//In my application in certain situation I get a List[UserCommand] (database query) and I want to invoke processCommand their relevant
//handlers. How do I get this to work ?
val command: UserCommand = CreateUser("userId2")
CommandHandlerRunner.processCommand(command)
}
【问题讨论】:
-
如果
UserCommand是一个密封的特征,这应该可以使用 shapeless。 -
是的,它是
sealed trait。我已经更新了代码。我将尝试阅读 shapeless。
标签: scala