2016-04-19 4 views
0

In meiner App habe ich einen Supervisor, der einige Arbeiter erstellt. Jeder dieser Worker benötigt zwei QueueClients-Instanzen (mit unterschiedlichen Konfigurationen und unterschiedlichen Instanzen zwischen den Arbeitern). Ich bin neu zu guice und ich habe Probleme, diese Abhängigkeiten in Kinddarstellern zu injizieren.Inject-Service mit Guice zu Kind Schauspieler von der Fabrik zur Verfügung gestellt

Das ist meine Arbeiter Klasse:

object LegacyConsumer { 

    trait Factory { 
    def apply(): Actor 
    } 

} 

class LegacyConsumer @Inject()(
    eventsClient: QueueClient, 
    deadLetterClient: QueueClient 
) extends Actor with ActorLogging { 

    override def preStart(): Unit = { 
    log.error("prestart") 
    log.error(eventsClient.toString) 
    } 

    def receive: PartialFunction[Any, Unit] = { 
    case _ => 
     log.error("received message consumer") 
    } 
} 

Wie Sie ich brauche die beiden QueueClients für den Bau sehen:

meine Arbeiter
trait QueueClient { 
... 

    def numMessages: Int 
} 

class SqsClient @Inject()(name: String, key: String, secret: String, zone: String) extends Logging with QueueClient { 
... 
} 

Dies ist, wie ich versuche,

class LegacyConsumerSupervisor @Inject()(
    consumerFactory: LegacyConsumer.Factory, 
    @Named("numWorkers") workers: Int 
) 
    extends Actor with ActorLogging with InjectedActorSupport { 

    override def preStart(): Unit = { 
    (1 to workers).foreach { workerNumber => 
     val key = s"WORKER-$workerNumber" 
     injectedChild(consumerFactory(), key, _.withDispatcher("akka.legacy-consumer-dispatcher")) 
    } 
    } 
zu erstellen

Und zum Schluss sehen meine Bindungen so aus:

class ChatModule extends AbstractModule with ScalaModule with AkkaGuiceSupport{ 
    override def configure() { 
    bind[Actor].annotatedWith(Names.named(LegacyConsumerSupervisor.name)).to[LegacyConsumerSupervisor] 

    bind(classOf[Int]) 
     .annotatedWith(Names named "numWorkers") 
     .toInstance(ConfigurationHelper.getInt("chat.legacy.num-workers")) 

    bindActorFactory[LegacyConsumer, LegacyConsumer.Factory] 

    bind(classOf[QueueClient]) 
//  .annotatedWith(Names named "legacyEventsClient") 
     .toInstance(
      new SqsClient(
      ConfigurationHelper.getString("chat.legacy.events.name"), 
      ConfigurationHelper.getString("chat.legacy.events.key"), 
      ConfigurationHelper.getString("chat.legacy.events.secret"), 
      ConfigurationHelper.getString("chat.legacy.events.region") 
     ) 
     ) 

    bind(classOf[QueueClient]) 
//  .annotatedWith(Names named "legacyDeadLetterClient") 
     .toInstance(
      new SqsClient(
      ConfigurationHelper.getString("chat.legacy.dead-letter.name"), 
      ConfigurationHelper.getString("chat.legacy.dead-letter.key"), 
      ConfigurationHelper.getString("chat.legacy.dead-letter.secret"), 
      ConfigurationHelper.getString("chat.legacy.dead-letter.region") 
     ) 
     ) 
    } 
} 

Wie kann ich verschiedene Instanzen von Warteschlangenclients in jeden Worker injizieren? Alle LegacyEventsClients und LegacyDeadLetterClients haben die gleiche Konfiguration (basierend auf typesafe config). Hat die Lösung etwas mit unterstützter Injektion zu tun?

Der Fehler Ich erhalte jetzt:

Eine Bindung an ... QueueClient wurde bereits konfiguriert ist, um ... configure (ChatModule.scala: 29). bei ... configure (ChatModule.scala: 40)

Also ich denke, das Problem ist über versuchen, die gleiche Bindung zweimal in verschiedene Instanzen injizieren ... Ich habe versucht, mit benannten Parametern, aber dann die gleiche Instanz zu tun Client LegacyConsumer

Grüße

Antwort

0

ich dies habe schließlich tat, um jeweils injiziert und es funktioniert:

Bindungen:

bind(classOf[QueueClient]) 
     .annotatedWith(Names named "legacyEventsClient") 
     .toProvider(new Provider[SqsClient] { 
     override def get = { 
      new SqsClient(
      ConfigurationHelper.getString("chat.legacy.events.name"), 
      ConfigurationHelper.getString("chat.legacy.events.key"), 
      ConfigurationHelper.getString("chat.legacy.events.secret"), 
      ConfigurationHelper.getString("chat.legacy.events.region") 
     ) 
     } 
     }) 

    bind(classOf[QueueClient]) 
     .annotatedWith(Names named "legacyDeadLetterClient") 
     .toProvider(new Provider[SqsClient] { 
     override def get = { 
      new SqsClient(
      ConfigurationHelper.getString("chat.legacy.dead-letter.name"), 
      ConfigurationHelper.getString("chat.legacy.dead-letter.key"), 
      ConfigurationHelper.getString("chat.legacy.dead-letter.secret"), 
      ConfigurationHelper.getString("chat.legacy.dead-letter.region") 
     ) 
     } 
     }) 

und in meiner Arbeiterklasse:

class LegacyConsumer @Inject()(
    @Named("legacyEventsClient") eventsClient: QueueClient, 
    @Named("legacyDeadLetterClient") deadLetterClient: QueueClient 
) extends Actor with ActorLogging { 

    override def preStart(): Unit = { 
    log.error("prestart") 
    } 

    def receive: PartialFunction[Any, Unit] = { 
    case _ => 
     log.error("received message consumer") 
    } 
}