2017-07-17 1 views
0

Je souhaite injecter deux acteurs dans un contrôleur de jeu via DI. Injecter un acteur fonctionne absolument bien et je peux envoyer un message à cet acteur sans aucun problème. Cependant, lors de l'injection d'un second acteur et envoyer un message, je reçois l'erreur de compilation suivante:'valeurs implicites ambiguës' lors de l'injection de deux acteurs dans le contrôleur de jeu

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] 

Mon contrôleur ressemble à ceci:

class MyController @Inject()(
              implicit system: ActorSystem, 
              materializer: Materializer, 
              @Named("FooSupervisor") fooSupervisor: ActorRef, 
              @Named("BarSupervisor") barSupervisor: ActorRef 
             ) extends Controller { 


} 

Et le module se présente comme suit:

class Module extends AbstractModule with ScalaModule with AkkaGuiceSupport { 

    def configure() { 
    // .... 
    bindActor[FooSupervisor]("FooSupervisor") 
    bindActor[BarSupervisor]("BarSupervisor") 
    () 
    } 

} 

Comment puis-je résoudre ce problème?

Répondre

2

Vous définissez les deux acteurs comme des paramètres implicites. Modifiez la signature comme suit:

class MyController @Inject()(
    @Named("FooSupervisor") fooSupervisor: ActorRef, 
    @Named("BarSupervisor") barSupervisor: ActorRef 
)(implicit system: ActorSystem, materializer: Materializer 
) extends Controller { 
0

J'ai essayé d'injecter l'acteur dans le contrôleur d'un fournisseur.

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") 
    } 
} 

Le module doit lier l'acteur reef.

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]) 
} 

Si vous avez besoin d'un matérialisateur et d'un acteur, faites-les passer comme des paramètres implicites. Puisque nous avons injecté l'acteur lui-même, nous n'avons pas besoin d'un acteur pour interagir avec les acteurs. Mais en fonction de ce que vous faites à l'intérieur du contrôleur - si vous avez besoin de choses comme le matérialisateur ou le système d'acteur qui les rend implicite, c'est mieux.

+0

fyi - J'ai utilisé guice 4.1.0 pour tester le code ci-dessus. – Prashanth