После много исследований я хотел обновить мои результаты здесь. Хотя мне удалось решить мою конкретную проблему, как показано ниже, здесь еще многое нужно сказать.
Мой конкретное решение первой -
Вместо DbController, я wraped моей службы, как показано ниже, и вводят его в случае необходимости -
trait Db {
def post
}
class InfluxDb @Inject() (ws: WSClient) extends Db {
val logger = LoggerFactory.getLogger(classOf[InfluxDb])
logger.info("InfluxDb: Initiatlized")
def post = {
val req = ws.url("http://localhost:9086/write")
.withQueryString("db" -> "db1")
.withHeaders("Content-Type" -> "application/json")
.post("job_id,command=PUT value=99")
logger.debug("InfluxDb: Post")
}
}
Сказав, что, впрыскивая материал дал мне массу проблем. Я, наконец, понял, что есть несколько случаев, отчетливый использование здесь -
- Использование Акку & Guice и не используя Playframework
- Использование Playframework + Akka + Guice и нагнетание верхнего уровня актера
- Использование Playframework + Akka + Guice и инъекции детских актеров
- Использование playframework + Akka + Guice НО создание не "инъекции g "ваш актер верхнего уровня & Система исполнителей.
Вот как вы могли бы решить каждый из вышеперечисленных.
- Для (1) - Обратитесь к guice akka tutorial
- Для (2) & (3) - см Playframework Documentation
- Для (4) Это немного сложнее
Вы будете необходимо расширить «IndirectActorProducer», а затем использовать его для создания вашего ActorRef. Проблема заключается в том, что «реквизит» не знает, как взаимодействовать с Guice. Это также является частью решения в (1)
Нижеприведенный пример кода показывает все 4 варианта использования и компилирует. В коде ниже
ParentActor - указывает на использование корпуса (2) выше, ChildActor для использования корпуса (3) и ParentActor_2 & ChildActor_2 для использования корпуса (4).
// play imports
import play.api.mvc._
import play.api.Logger
import play.api.mvc.Results
// actor imports
import akka.actor.{Actor, ActorSystem, ActorRef, Props, IndirectActorProducer}
// DI imports
import com.google.inject.{Injector, AbstractModule, Key, Provides}
import javax.inject._
import com.google.inject.assistedinject.Assisted
import play.libs.akka.AkkaGuiceSupport
import play.api.libs.concurrent.InjectedActorSupport
class MainCntrlr @Inject() (injector : Injector,
@Named("PActor") pa: ActorRef,
cfP: ParentActor_2.Factory)
extends Controller {
Logger.debug("MainCntrlr: created")
val pa_2 = ActorSystem("test")
.actorOf(Props(classOf[GuiceActorProducer], injector, "PActor_2"), "PA_2")
pa ! 12
pa_2 ! 100
def index = Action { Ok (views.html.index.render()) }
}
class ParentActor @Inject() (cf: ChildActor.Factory) extends Actor with InjectedActorSupport {
Logger.debug("ParentActor: created")
val cactor = injectedChild(cf(2),"childActor")
cactor ! 10
def receive = { case _ => Logger.debug("ParentActor received msg") }
}
object ChildActor { trait Factory { def apply(i: Int) : Actor } }
class ChildActor @Inject()(i: Injector, @Assisted v: Int) extends Actor {
Logger.debug("ChildActor: created with value " + v.toString)
def receive = { case _ => Logger.debug("ChildActor received msg") }
}
class ParentModule extends AbstractModule with AkkaGuiceSupport {
def configure() = {
bindActor(classOf[ParentActor],"PActor")
bindActorFactory(classOf[ChildActor], classOf[ChildActor.Factory])
bindActorFactory(classOf[ParentActor_2], classOf[ParentActor_2.Factory])
bindActorFactory(classOf[ChildActor_2], classOf[ChildActor_2.Factory])
}
}
object ParentActor_2 { trait Factory { def apply() : Actor } }
class ParentActor_2 @Inject() (cf: ChildActor_2.Factory) extends Actor with InjectedActorSupport {
Logger.debug("ParentActor_2: created")
val cactor = injectedChild(cf(4),"childActor_2")
cactor ! 10
def receive = { case _ => Logger.debug("ParentActor_2 received msg") }
}
object ChildActor_2 { trait Factory { def apply(i: Int) : Actor } }
class ChildActor_2 @Inject() (i: Injector, @Assisted v: Int) extends Actor {
Logger.debug("ChildActor_2: created with value " + v.toString)
def receive = { case _ => Logger.debug("ChildActor_2 received msg") }
}
class GuiceActorProducer(val injector: Injector, val actorName: String)
extends IndirectActorProducer {
override def actorClass = classOf[ParentActor_2]
override def produce() =
injector.getBinding(Key.get(classOf[ParentActor_2])).getProvider.get()
}
А потом в моей application.conf
play.modules.enabled += "package.ParentModule"
Вы можете использовать инъекции зависимостей для создания актеров, смотрите здесь: https://www.playframework.com/documentation/2.5.x/ScalaAkka# Зависимость-впрыскивающие субъекты – Haspemulator
Haspemulator, спасибо за ваш ответ. Он ответил на части моего первоначального вопроса (как я могу влиться в актера), но не решил мою проблему. Я перефразировал части своего вопроса, чтобы это было более ясно. –
Вот что, наконец, –