【问题标题】:How to inject services into actors using the Play 2.4?如何使用 Play 2.4 将服务注入演员?
【发布时间】:2015-12-21 03:40:17
【问题描述】:

我能够毫无问题地将服务注入我的应用程序类。但不知何故,我无法注入演员本身。

我的演员:

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

我的演员的同伴对象:

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

【问题讨论】:

    标签: scala playframework dependency-injection akka guice


    【解决方案1】:

    你可以让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"
    }
    

    不想麻烦的可以直接调用injector,别忘了导入Application到scope:

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

    【讨论】:

    • 我有,ActorModule 类使用 AkkaGuiceSupport 扩展了 AbstractModule。我认为 guice 知道演员,但它不知道如何将服务注入演员?
    • 你的演员是一个对象。它必须是类。
    • 我更新了 OP...我有一个演员类然后是一个演员对象,两者都具有相同的名称,这有关系吗?
    • 不确定Guice 如何处理伴随对象。
    • 我能够在github.com/rocketraman/activator-akka-scala-guice#master 之后将事情作为一个独立的 scala 应用程序运行,但是当我将内容移植到 play 应用程序时,一切都崩溃了 =/
    猜你喜欢
    • 1970-01-01
    • 2016-06-07
    • 1970-01-01
    • 2016-02-26
    • 2015-09-23
    • 1970-01-01
    • 2015-10-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多