2017-09-16 111 views
2

我有一个WebSocket控制器,每个连接的演员处理器创建:如何将注入()到具有构造函数参数的类中?

class WebSocketController @Inject()(cc: ControllerComponents)(implicit exc: ExecutionContext) { 
    def socket: WebSocket = WebSocket.accept[JsValue, JsValue] { request => 
    ActorFlow.actorRef { out => // Flow that is handled by an actor from 'out' ref 
     WebSocketActor.props(out) // Create an actor for new connected WebSocket 
    } 
    } 
} 

和演员处理我需要ReactiveMongo工作中:

trait ModelDAO extends MongoController with ReactiveMongoComponents { 
    val collectionName: String 
    ... 
} 
class UsersCollection @Inject()(val cc: ControllerComponents, 
           val reactiveMongoApi: ReactiveMongoApi, 
           val executionContext: ExecutionContext, 
           val materializer: Materializer) 
    extends AbstractController(cc) with ModelDAO { 
    val collectionName: String = "users" 
} 

所以,通常的方法是@Inject( )目标类中的UsersCollection。由于演员的情况下创建内部WebSocketActor同伴对象

class WebSocketActor @Inject()(out: ActorRef, users: UsersCollection) extends Actor { ... } 

object WebSocketActor { 
    def props(out: ActorRef) = Props(new WebSocketActor(out)) 
} 

如何使用UsersCollectionWebSocketActor内,但我不能这样做?

+0

可能这是相关的吗? https://stackoverflow.com/q/45774470/1080523 – rethab

回答

1

您可以创建演员谁的依赖关系将通过Play自动注入。没问题。 (https://www.playframework.com/documentation/2.6.x/ScalaAkka)在网络套接字的情况下

道具的演员的预期,而不是演员(或ActorRef)本身。

ActorFlow.actorRef { out => // Flow that is handled by an actor from 'out' ref 
    WebSocketActor.props(out) // <- ACTOR IS NOT CREATED HERE, WE RETURN PROPS 
} 

所以在这种情况下没有办法自动做到这一点(至少我没有找到它)。

你可以做的是手动通过UsersCollection

class WebSocketController @Inject()(cc: ControllerComponents, usersCollection: UsersCollection)(implicit exc: ExecutionContext) { 
    def socket: WebSocket = WebSocket.accept[JsValue, JsValue] { request => 
    ActorFlow.actorRef { out => // Flow that is handled by an actor from 'out' ref 
     WebSocketActor.props(out, usersCollection) //<- ACTOR IS NOT CREATED HERE, WE RETURN PROPS 
    } 
    } 
} 

注意到我注射UsersCollectionWebSocketController并将它传递给道具。

简单,我没有看到任何缺点。

+0

我想问的是如何注入'ActorRef' – cchantep

+0

请看[截图](https://snag.gy/X0DguQ.jpg) –

+0

谢谢对于答案,缺点是在那些我有更多的收藏(用户,表等)。将所有这些手动传递给演员是否正常? –

0

我有一个事件处理程序模块,在我的应用程序启动时基本实例化了所有的actor。事件处理程序都是演员,所以你可以做这样的:

class EventHandlerBootstrap @Inject() (system: ActorSystem, app: Application) { 
    EventHandlerBootstrap.handlers.foreach { 
    case (h, n) => system.actorOf(Props(app.injector.instanceOf(h)), n) 
    } 
} 

//These Class[_ <: EventHandler] are classes of user defined actors each with their own 
// dependencies which guice will take care of automattically. 
object EventHandlerBootstrap { 
    val handlers: Map[Class[_ <: EventHandler], String] = Map(
    classOf[UserRegisteredHandler] -> "user-registered-handler", 
    classOf[CustomerOrderCreatedHandler] -> "customer-order-created-handler", 
    classOf[DisputeClosedHandler] -> "dispute-closed-handler", 
    classOf[Throttle] -> "throttle" 
) 
} 

,并在模块内部运行我这样的引导程序:

class EventModule extends ScalaModule with AkkaGuiceSupport { 

    override def configure(): Unit = { 
    bind[EventHandlerBootstrap].asEagerSingleton() 
    } 
} 

如果你ofcourse不急于盲目跟从我的食谱你仍然可以拿出注入你的演员和他们的依赖的事实完全由guice支持,如上所示。希望它会帮助

相关问题