在带有DI的播放2.4中,如何在“安全"中使用服务类.特征? [英] In Play 2.4 with DI, how to use a service class in "Secured" trait?

查看:51
本文介绍了在带有DI的播放2.4中,如何在“安全"中使用服务类.特征?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是来自Play文档的授权示例(2.0版. 4;我试图找到此文档的较新版本,但找不到):

Here's an authorisation example from Play Documentation (version 2.0.4; I tried to find a newer version of this document but couldn't):

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

总的来说,这非常简单,我想使用类似的东西.

Overall this is pretty straightforward, and I'd like to go with something like this.

现在,在Play 2.4中,推荐的方法不再是 来使用单例(如上述UserDAO),而是改为使用类和运行时DI(请参见

Now, in Play 2.4 the recommended way is not to use singletons anymore (like UserDAO above), but classes and runtime DI instead (see migration guide, or DI docs).

例如,我的服务和存储库类的定义如下:

For example, my service and repository classes are defined like this:

class AuthService @Inject()(accountRepo: AccountRepository) { }

class AccountRepository { }

使用Play 2.4和DI时,推荐的/正确的"/最简单的方式来获得服务或DAO(例如,在我的情况下为AuthService,在doc示例中为UserDAO)是什么?像Secured这样的特质?

With Play 2.4 and DI in use, what is the recommended / "correct" / simplest way to get hold of a service or DAO (like AuthService in my case, or UserDAO in the doc example) in a trait like Secured?

或者您今天是否应该以不同于使用这种特征的另一种方式来实现对控制器的授权?

Or are you nowadays supposed to implement authorisation for controllers in a whole another way than using such trait?

我可以按照以下方式进行工作:

I can make it work along these lines:

trait Secured {
  val authService = GuiceUtils.inject[AuthService]    
  // ...
}

使用这样的助手:

object GuiceUtils {
  lazy val injector = new GuiceApplicationBuilder().injector()    
  def inject[T: ClassTag]: T = injector.instanceOf[T]
}

但是根据相关问题中的答案:

在Play中,您可以直接在应用程序中使用喷油器 特征是范围.但这不被认为是良好的做法 生产代码.

In Play you could use the injector directly as long as the Application trait is in scope. But this isn't considered good practice in production code.

如果是这样,在此用例中什么被认为是好的做法?

If that is true, what is considered good practice in this use case?

推荐答案

我认为最简单的方法是在trait中声明authService,但使其保持抽象,然后由对其进行扩展的控制器处理注入(我相信是MessagesApi/I18nSupport注入的工作方式).因此,您可以这样做:

I think the simplest approach would be to declare the authService in your trait but keep it abstract, then have the controller which extends it handle the injection (I believe this is how MessagesApi/I18nSupport injection works). So you could do:

trait Secured {
  val authService: AuthService
  ...
}

controller Application @Inject()(override val authService: AuthService) extends Controller with Secured {
  ...
}

这篇关于在带有DI的播放2.4中,如何在“安全"中使用服务类.特征?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆