9

WebSocket.acceptWithActor instantiates một diễn viên Akka mới mà không sử dụng Guice.WebSocket.acceptWithActor và @Inject() trong diễn viên (Play 2.5)

Với Play 2.4, sử dụng bộ phun cho diễn viên của tôi vẫn có thể bằng cách nhập play.api.Play.current.

Snippet từ 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)) 
} 

Nhưng trong Chơi 2.5, play.api.Play.current bị phản đối. Tôi vẫn có thể tiêm ReactiveMongoApi vào diễn viên của mình bằng cách nào? Cách được khuyến nghị sử dụng một thể hiện của ReactiveMongoApi trong diễn viên của tôi là gì?

Đây là mã của tôi mà làm việc với Play 2.4 vì tùy chỉnh của tôi diễn viên lớp ClientActor có quyền truy cập vào ReactiveMongoApi qua 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) 
    } 

} 

Trả lời

3

Tôi không nghĩ rằng đây là có thể. Trích dẫn James Roper:

Những người trợ giúp Play cung cấp cho diễn viên tiêm phụ thuộc phù hợp với một số trường hợp sử dụng hạn chế. Mặc dù, những người trợ giúp thực sự chỉ là những trình bao bọc rất mỏng so với một số yêu cầu chung - chúng không cần thiết chút nào. Trong trường hợp hỗ trợ diễn viên WebSocket của Play, điều này là, nói chung bạn muốn tự khởi tạo diễn viên vì bạn phải bằng cách nào đó truyền nó ra ActorRef. Vì vậy, bạn có thể làm điều này bằng cách sử dụng Guice hỗ trợ tiêm, và xác định một giao diện yếu tố mà đưa ra các diễn viên ref (và bất kỳ đối số khác bạn muốn vượt qua nó), hoặc đơn giản là instantiate nó bằng tay, đi phụ thuộc từ bộ điều khiển để các diễn viên , ví dụ:

class MyController @Inject() (myDep: MyDep) extends Controller { 
    def socket = WebSocket.acceptWithActor[String, String] { request => out => 
    MyWebSocketActor.props(out, myDep) 
    } 
} 
0

Phát 2.5 đã hỗ trợ DI.

Chữ ký MidiActor cần được sửa đổi như đã nói bên dưới.

class [email protected]() (configuration: Configuration, @Named("midi-discovery-actor") midiDiscoveryActor: ActorRef) extends Actor with InjectedActorSupport{ 
....... 
} 

Tạo module mới và cho phép trong application.conf

play.modules.enabled += MyModule 

class MyModule extends AbstractModule with AkkaGuiceSupport { 
    def configure = { 
    bindActor[MidiDiscoveryActor]("midi-discovery-actor") 
    bindActor[MidiActor]("midi-actor") 
    } 
} 

Thay đổi điều khiển của bạn như sau

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

} 
Các vấn đề liên quan