2015-06-28 19 views
16

vì Play Framework 2.4 có khả năng sử dụng tiêm phụ thuộc (với Guice).Play Framework: Dependency Inject Action Builder

Trước khi tôi sử dụng các đối tượng (ví dụ AuthenticationService) trong ActionBuilders tôi:

object AuthenticatedAction extends ActionBuilder[AuthenticatedRequest] { 
    override def invokeBlock[A](request: Request[A], block: (AuthenticatedRequest[A]) => Future[Result]): Future[Result] = { 
    ... 
    AuthenticationService.authenticate (...) 
    ... 
    } 
} 

Bây giờ AuthenticationService không phải là một đối tượng nữa, nhưng một lớp. Tôi vẫn có thể sử dụng số AuthenticationService trong số ActionBuilder của mình như thế nào?

Trả lời

26

Xác định trình tạo hành động của bạn bên trong một đặc điểm với dịch vụ xác thực dưới dạng trường trừu tượng. Sau đó trộn chúng vào bộ điều khiển của bạn, trong đó bạn tiêm dịch vụ. Ví dụ:

trait MyActionBuilders { 
    // the abstract dependency 
    def authService: AuthenticationService 

    def AuthenticatedAction = new ActionBuilder[AuthenticatedRequest] { 
    override def invokeBlock[A](request: Request[A], block(AuthenticatedRequest[A]) => Future[Result]): Future[Result] = { 
     authService.authenticate(...) 
     ... 
    } 
    } 
} 

và bộ điều khiển:

@Singleton 
class MyController @Inject()(authService: AuthenticationService) extends Controller with MyActionBuilders {  
    def myAction(...) = AuthenticatedAction { implicit request => 
    Ok("authenticated!") 
    } 
} 
+2

Tôi cần thêm 'val' trước khi 'authService' trong' MyController' nếu không compilator phàn nàn rằng phương pháp authService không được định nghĩa – Isammoc

+0

này không làm việc cho tôi với một val hoặc def, nói rằng lớp điều khiển cần phải được trừu tượng bởi vì def/val không được xác định – Daniel

0

Tôi thích chấp nhận câu trả lời nhưng vì một lý do trình biên dịch sẽ không nhận ra tài liệu tham khảo authService. Tôi nhận được xung quanh điều này khá dễ dàng bằng cách chỉ cần gửi các dịch vụ trong chữ ký phương pháp, một ...

class Authentication @Inject()(authenticationService: AuthenticationService) extends Controller with ActionBuilders { 

    def testAuth = AuthenticatedAction(authenticationService).async { implicit request => 
    Future.successful(Ok("Authenticated!")) 
    } 

} 
+0

Tôi chỉ cần kiểm tra và tôi thấy không có lý do câu trả lời được chấp nhận sẽ không biên dịch! –

17

Tôi không thích cách thức được yêu cầu kế thừa trong ví dụ trên. Nhưng dường như nó có thể chỉ đơn giản là quấn một object bên trong lớp:

class Authentication @Inject()(authService: AuthenticationService) { 
    object AuthenticatedAction extends ActionBuilder[Request] { 
    def invokeBlock[A](request: Request[A], block: (Request[A]) => Future[Result]) = { 
     // Do your thing wit the authService... 
     block(request) 
    } 
    } 
} 

class YourController @Inject() (val auth: Authentication) extends Controller (
    def loggedInUser = auth.AuthenticatedAction(parse.json) { implicit request => 
    // ... 
    } 
} 
Các vấn đề liên quan