Oto authorisation example from Play Documentation (wersja 2.0.4; starałem się znaleźć nowszą wersję tego dokumentu, ale nie mogłyby):W Play 2.4 z DI, jak korzystać z klasy usług w "zabezpieczonej" funkcji?
trait Secured {
def username(request: RequestHeader) = request.session.get(Security.username)
def onUnauthorized(request: RequestHeader) = Results.Redirect(routes.Auth.login)
def withAuth(f: => String => Request[AnyContent] => Result) = {
Security.Authenticated(username, onUnauthorized) { user =>
Action(request => f(user)(request))
}
}
def withUser(f: User => Request[AnyContent] => Result) = withAuth { username => implicit request =>
UserDAO.findOneByUsername(username).map { user =>
f(user)(request)
}.getOrElse(onUnauthorized(request))
}
}
Ogólnie jest całkiem prosta, i chciałbym iść z czymś to.
Teraz, zagraj 2.4 zalecanym sposobem jest nie się już używać pojedynczych (jak UserDAO powyżej), ale klasy i wykonawcze DI zamiast (patrz migration guide lub DI docs).
Na przykład, mój serwis i klas repozytorium są określone następująco:
class AuthService @Inject()(accountRepo: AccountRepository) { }
class AccountRepository { }
z luzem 2.4 i DI w użyciu, co jest zalecane/„poprawny”/Najprostszym sposobem, aby zdobyć usługi lub DAO (np. AuthService
w moim przypadku, lub UserDAO
w dokumencie doc) w cechach takich jak Secured
?
Czy obecnie ma pan wprowadzić autoryzację dla kontrolerów w zupełnie inny sposób niż używanie takiej cechy?
mogę pracować wzdłuż tych linii:
trait Secured {
val authService = GuiceUtils.inject[AuthService]
// ...
}
Korzystanie pomocnika takiego:
object GuiceUtils {
lazy val injector = new GuiceApplicationBuilder().injector()
def inject[T: ClassTag]: T = injector.instanceOf[T]
}
Jednak zgodnie z odpowiedzią w related question:
W Play możesz użyć wtryskiwacza bezpośrednio tak długo, jak cecha aplikacji jest w zakresie. Ale nie jest to uważane za dobrą praktykę w kodzie produkcyjnym .
Jeśli to prawda, to, co jest za dobrą praktykę w tym przypadku użycia?
Dzięki, naprawdę bardzo proste! (Musiał dodać 'override val', aby go skompilować.) – Jonik
, ale w ten sposób kontroler ma wiedzę na temat implementacji - authService - która może być używana tylko w funkcji" Secured ". Czy istnieje jakiś sposób, aby wstrzyknąć go tylko do cechy? Podobnie jak w strukturze ciasta? – freakman