我想通过DI将两个演员注入Play控制器。注入一个演员的工作非常好,我可以毫无问题地向这个演员发送信息。但是,当注入第二个actor并发送消息时,我收到以下编译错误:
play.sbt.PlayExceptions$CompilationException: Compilation error[ambiguous implicit values:
both value fooSupervisor in class MyController of type akka.actor.ActorRef
and value barSupervisor in class MyController of type akka.actor.ActorRef
match expected type akka.actor.ActorRef]
我的控制器看起来像这样:
class MyController @Inject()(
implicit system: ActorSystem,
materializer: Materializer,
@Named("FooSupervisor") fooSupervisor: ActorRef,
@Named("BarSupervisor") barSupervisor: ActorRef
) extends Controller {
}
该模块如下所示:
class Module extends AbstractModule with ScalaModule with AkkaGuiceSupport {
def configure() {
// ....
bindActor[FooSupervisor]("FooSupervisor")
bindActor[BarSupervisor]("BarSupervisor")
()
}
}
我该如何解决这个问题?
答案 0 :(得分:2)
您将两个actor定义为隐式参数。像这样更改签名:
class MyController @Inject()(
@Named("FooSupervisor") fooSupervisor: ActorRef,
@Named("BarSupervisor") barSupervisor: ActorRef
)(implicit system: ActorSystem, materializer: Materializer
) extends Controller {
答案 1 :(得分:0)
我尝试将actorRef从提供者注入控制器。
import javax.inject._
import akka.actor.ActorRef
import play.api.mvc._
@Singleton
class HomeController @Inject()(@Named("actor1") val actor1: ActorRef, @Named("actor2") val actor2: ActorRef) extends Controller {
def index = Action {
actor1 ! "hello actor1"
actor2 ! "hello actor2"
Ok("Hello")
}
}
模块应绑定actorRef。
import javax.inject.{Inject, Provider}
import com.google.inject.AbstractModule
import net.codingwell.scalaguice.ScalaModule
import actors.{Actor1, Actor2}
import akka.actor.{ActorRef, ActorSystem, Props}
class Module extends AbstractModule with ScalaModule{
override def configure() = {
bind[ActorRef].annotatedWithName("actor1").toProvider[Actor1Provider]
bind[ActorRef].annotatedWithName("actor2").toProvider[Actor2Provider]
}
}
class Actor1Provider @Inject() (system: ActorSystem) extends Provider[ActorRef]{
override def get(): ActorRef = system.actorOf(Props[Actor1])
}
class Actor2Provider @Inject() (system: ActorSystem) extends Provider[ActorRef]{
override def get(): ActorRef = system.actorOf(Props[Actor2])
}
如果你需要一个物质化器和actorSystem,请将它们作为隐式参数传递。由于我们注入了actorRef本身,我们可能不需要actorSystem来与actor进行交互。但取决于你在控制器内做了什么 - 如果你需要像物化器或actorSystem这样的东西让它们隐含更好。