WebSocket.acceptWithActor
在没有使用Guice的情况下实例化一个新的Akka演员。
使用Play 2.4,通过导入play.api.Play.current
仍然可以使用我的演员的注入器。
来自ReactiveMongo documentation的片段:
import scala.concurrent.Future
import play.api.Play.current // should be deprecated in favor of DI
import play.api.libs.concurrent.Execution.Implicits.defaultContext
import play.modules.reactivemongo.ReactiveMongoApi
import play.modules.reactivemongo.json.collection.JSONCollection
object Foo {
lazy val reactiveMongoApi = current.injector.instanceOf[ReactiveMongoApi]
def collection(name: String): Future[JSONCollection] =
reactiveMongoApi.database.map(_.collection[JSONCollection](name))
}
但是在Play 2.5中,play.api.Play.current
已被弃用。我怎样才能在我的演员中注入ReactiveMongoApi
?在我的演员中使用ReactiveMongoApi
实例的推荐方法是什么?
以下是适用于Play 2.4的代码,因为我的自定义角色类ClientActor
可以通过ReactiveMongoApi
访问current.injector.instanceOf[ReactiveMongoApi]
:
@Singleton
class Application @Inject() (system: ActorSystem) extends Controller {
val midiDiscoveryActor = system.actorOf(MidiDiscoveryActor.props, "midi-discovery-actor")
val midiActor = system.actorOf(MidiActor.props(midiDiscoveryActor), "midi-actor")
def index(page: String) = Action {
Ok(views.html.index(page))
}
def bidirectional = WebSocket.acceptWithActor[JsValue, JsValue] { request => out =>
ClientActor.props(out, midiActor, midiDiscoveryActor)
}
}
答案 0 :(得分:3)
我不认为这是可能的。引用James Roper:
Play为依赖注入actor提供的助手适用于有限数量的用例。虽然,帮助者实际上只是非常薄的包装超过了一些常见的要求 - 根本不需要它们。在Play的WebSocket actor支持的情况下,事情是,通常你想手动实例化actor,因为你必须以某种方式将它传递给ActorRef。所以,您可以使用Guice辅助注入执行此操作,并定义一个因子接口,该接口使用out actor ref(以及您想要传递给它的任何其他参数),或者只是手动实例化它,将依赖项从控制器传递给actor ,例如:
class MyController @Inject() (myDep: MyDep) extends Controller { def socket = WebSocket.acceptWithActor[String, String] { request => out => MyWebSocketActor.props(out, myDep) } }
答案 1 :(得分:0)
Play 2.5内置支持DI。
需要修改MidiActor签名,如下所述。
class MidiActor@Inject() (configuration: Configuration, @Named("midi-discovery-actor") midiDiscoveryActor: ActorRef) extends Actor with InjectedActorSupport{
.......
}
创建新模块并在application.conf中启用
play.modules.enabled += MyModule
class MyModule extends AbstractModule with AkkaGuiceSupport {
def configure = {
bindActor[MidiDiscoveryActor]("midi-discovery-actor")
bindActor[MidiActor]("midi-actor")
}
}
按以下方式更改您的控制器
@Singleton
class Application @Inject() (system: ActorSystem,@Named("midi-actor") midiActor: ActorRef,
@Named("midi-discovery-actor") midiDiscoveryActor: ActorRef) (implicit ec: ExecutionContext) extends Controller {
def index(page: String) = Action {
Ok(views.html.index(page))
}
def bidirectional = WebSocket.acceptWithActor[JsValue, JsValue] { request => out =>
ClientActor.props(out, midiActor, midiDiscoveryActor)
}
}