Play for Scala:Scala 对象作为 DAO



我习惯了像 Ruby on Rails 或 PHP 中的 Laravel 这样的框架,在这些框架中我有像 User 这样的模型,当我想对模型进行查询时(例如,获取数据库中的所有用户),我会做类似 User::all() 的事情。

我是 Play for Scala 和 Slick 的新手,我已经看到的所有项目和文档都使用 DAO 通过模型访问数据库。我认为 Scala object是我需要的(或者至少我已经习惯了),所以我不需要到处注入 DAO 类。

对于DAO,我做了这样的事情:

class Application @Inject()(adminDAO: AdminDAO) extends Controller {
  def index = Action.async {
    adminDAO.all() map { case admins =>
      Ok(Json.toJson(admins))
    }
  }
}

对于一个对象(并且不知道),我希望做这样的事情:

class Application extends Controller {
  def index = Action.async {
    Admin.all() map { case admins =>
      Ok(Json.toJson(admins))
    }
  }
}

尝试实现"DAO"object我发现几乎不可能在不使用已弃用Play.current的情况下注入 Play Application 上下文。这种弃用和缺乏注入上下文的方法(或者至少我没有找到它)对我来说听起来很奇怪。我开始认为我的想法是错误的。使用 Scala object 作为 DAO 真的是个好主意吗?

它归结为依赖注入 (DI) 与硬编码依赖关系。您的第一个示例使用 DI,第二个示例对Admin DAO 的依赖关系进行硬编码。Play 团队决定在最近的版本中使用 DI,以删除全局状态(有关为什么全局状态是一件坏事的讨论,请参阅此处示例):

现在玩,开箱即用,使用Guice提供的依赖注入。 这是将全局状态从 Play,我们希望在Play 3.0版本中完成。

因此,当涉及到 Play 时,正确的方法是您的示例 1,纯粹基于您反对游戏的事实,使用对象和硬编码依赖项确实是不可取的(但是 DI 也有很多优点)。

不太精通Ruby,但据我所知,不需要Java/Scala中的框架DI(例如Guice),因为Ruby具有某些语言功能可以以不同的方式解决问题,这可能就是为什么您想知道这一切的全部意义。我建议你阅读一些关于Java/Scala上下文中的依赖注入的信息,这应该弄清楚它是如何工作的,它解决了什么问题以及(缺点)是什么(既然你知道Ruby,为什么Ruby不需要它)。

尝试实现"DAO"对象,我发现几乎不可能 以注入 Play 应用程序上下文而不使用 Play.current 已弃用。这种弃用和没有办法 注入上下文(或至少我没有找到它)声音 对我来说很奇怪。

您应该能够简单地将应用程序上下文注入您的 DAO,例如:

class AdminDao @Inject()(val application : Application) { 

然后您就有可用的应用程序。这相当于已弃用的

val application = Play.current

在这两种情况下,您都会捕获正在运行的Application。它背后的 dedentencency 注入框架确保以递归方式解析依赖关系,即当您在控制器中依赖您的 DAO 时,它会注意到 DAO 本身取决于应用程序。它解析应用程序,将其注入新的 DAO 实例,最后将其注入您的控制器。

最后但并非最不重要的是,像往常一样有很多方法通向罗马:也许ActiveSlick是你觉得有用的东西(免责声明:我自己没有尝试过)。

最新更新