如何使用Play 2.4向actor注入服务



我可以毫无问题地将服务注入到我的Application类中。但不知怎么的,我却无法把这种感觉注入到演员身上。

我的演员:

class PollerCrow @Inject()(
     @Named("pollService") pollService: PollService[List[ChannelSftp#LsEntry]]
     , @Named("redisStatusService") redisStatusService: StatusService
     , @Named("dynamoDBStatusService") dynamoDbStatusService: StatusService
) extends BaseCrow {
... impl and stuff ...
}

我的actor的同伴对象:

object PollerCrow extends NamedActor {
  override def name: String = this.getClass.getSimpleName
  val filesToProcess = ConfigFactory.load().getString("poller.crow.files.to.process")    
  def props = Props[PollerCrow]
}

当我运行它时,我得到以下内容:

IllegalArgumentException: no matching constructor found on class watcher.crows.PollerCrow for arguments []

我该如何解决这个问题?

编辑:

我已经绑定了我的演员:

class ActorModule extends AbstractModule with AkkaGuiceSupport {
  override def configure() {
    bindPollerActors()
  }
  private def PollActors() = {
    bindActor[PollerCrow](PollerCrow.name)
  }
}
编辑2:

类的附加细节:

abstract class BaseCrow extends Crow with Actor with ActorLogging
class PollerCrow @Inject()(
            @Named(ServiceNames.PollService) pollService: PollService[List[ChannelSftp#LsEntry]]
          , @Named(ServiceNames.RedisStatusService) redisStatusService: StatusService
          , @Named(ServiceNames.DynamoDbStatusService) dynamoDbStatusService: StatusService
) extends BaseCrow {
  override def receive: Receive = {
    ...
  }
}
object PollerCrow extends NamedActor {
  override def name: String = this.getClass.getSimpleName
  def props = Props[PollerCrow]
}
trait NamedActor {
  def name: String
  final def uniqueGeneratedName: String = name + Random.nextInt(10000)
}

你可以让Guice知道你的演员。这是一个简洁的方法:

import com.google.inject.AbstractModule
import play.api.libs.concurrent.AkkaGuiceSupport

class ActorModule extends AbstractModule with AkkaGuiceSupport {
  override def configure(): Unit =  {
    bindActor[YourActor]("your-actor")
  }
}
@Singleton
class YourActor @Inject()(yourService: IYourService) extends Actor {
  override def receive: Receive = {
    case msg => unhandled(msg)
  }
}

application.conf:

play.modules {
  enabled += "ActorModule"
}

对于那些不想麻烦的人,只需直接调用注入器,不要忘记将Application导入范围:

Play.application.injector.instanceOf[YourService]
Play.application.injector.instanceOf(BindingKey(classOf[YourService]).qualifiedWith("your-name"));

最新更新