title: Passing a constructor argument to a Play managed Actor
body: <p>I have a supervisor and a worker actor. The worker calls a service. All these are managed by Play(/Guice). </p>
  
  <p>Here is a simplification of the code: </p>
  
  <pre><code>class SupervisorActor @Inject()(workerFactory: WorkerActor.Factory, serviceA: AService)
      extends Actor
      with InjectedActorSupport {
  
    override def receive: Receive = {
      case message =&gt; injectedChild(workerFactory(serviceA), "childActorName").forward(message)
    }
  
  }
  
  class WorkerActor @Inject()(serviceA: AService) extends Actor {
    override def receive: Receive = {
      case _ =&gt; println(serviceA.getMessage())
    }
  }
  
  object WorkerActor {
    trait Factory {
      def apply(serviceA: AService): Actor
    }
  }
  
  @ImplementedBy(classOf[AServiceImpl])
  trait AService {
    def getMessage(): String
  }
  
  class AServiceImpl @Inject()(configuration: Configuration) extends AService {
    override def getMessage(): String = configuration.get[String]("id1")
  }
  </code></pre>
  
  <p>Module.scala(<code>configure</code> method):</p>
  
  <pre><code>bindActor[SupervisorActor]("supervisor")
  bindActorFactory[WorkerActor, WorkerActor.Factory]
  </code></pre>
  
  <p>Everything works perfectly. So far there is one instance of every class.</p>
  
  <p>Now, <code>AServiceImpl.getMessage()</code> needs to lookup a dynamic String (not just "id1" everytime). So changed it like so:</p>
  
  <pre><code>class AServiceImpl @Inject()(configuration: Configuration, propertyId: String) extends AService {
    override def getMessage(): String = configuration.get[String](propertyId)
  }
  </code></pre>
  
  <p>And removed <code>@ImplementedBy(classOf[AServiceImpl])</code> from <code>trait AService</code>.</p>
  
  <p>The idea was to instantiate 2 instances of the supervisor, worker &amp; service and wire them together in Module.scala. So I started out with this in Module.scala:</p>
  
  <pre><code>val aServive: AService = new AServiceImpl(configuration, "id1")
  </code></pre>
  
  <p>The challenge now is to get this instance injected into the Supervisor.  </p>
  
  <p>Appreciate any help on these:</p>
  
  <ol>
  <li>How do I access Guice managed WorkerActor.Factory in configure() (Module.scala) when the injector is still under construction?</li>
  <li>I tried using a @Provides method with the WorkerActor.Factory as a parameter. But bindActor() calls are only permitted in configure(). Not in @Provides methods.</li>
  <li>How do I have Play inject <code>workerFactory: WorkerActor.Factory</code> but supply my own <code>AService</code>?. As far as I can see, <code>bindActor(...)</code> does not seem to support this.</li>
  </ol>
  
  <p>Edit:</p>
  
  <p>My solution based on Renato's answer below for future use:</p>
  
  <p>I had to implement one ActorRef Provider for each instance of the actor (object graph) needed. Like so:</p>
  
  <pre><code>class PropertyId1SupervisorActorProvider @Inject()(configuration: Configuration,
                                                     workerFactory: WorkerActor.Factory,
                                                     actorSystem: ActorSystem)
      extends Provider[ActorRef] {
  
    override def get(): ActorRef = {
      val aService: AService = new AServiceImpl(configuration, "propertyId1")
      actorSystem.actorOf(Props(classOf[SupervisorActor], workerFactory, aService))
    }
  }
  </code></pre>
  
  <p>Then bind this provider in Module.scala:</p>
  
  <pre><code>bind(classOf[ActorRef])
        .annotatedWith(Names.named("propertyId1Actor"))
        .toProvider(classOf[PropertyId1SupervisorActorProvider])
  </code></pre>
  
  <p>This does need a bit of work to get another instance going. But this is the best solution I have for now. If there are recommendations on improving this, I am all ears.</p>