Play for Scala:作为 DAO 的 Scala 对象
Play for Scala: Scala object as DAO
我习惯于 Rails 上的 Ruby 或 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 以努力删除全局状态(有关为什么全局状态是坏事的讨论,请参阅 here for example):
Play now, out of the box, uses dependency injection provided by Guice.
This is part of a long term strategy to remove global state out of
Play, which we hope to complete in the Play 3.0 release.
因此,关于 Play 的正确方法是您的示例 1,使用对象并因此使用硬编码依赖项确实是不可取的,纯粹基于您反对游戏的事实(但是 DI 也有很多优点)。
我不太精通 Ruby,但据我所知,不需要 Java/Scala 中的带有框架(例如 Guice)的 DI,因为 Ruby具有某些语言功能来以不同的方式解决问题,这可能就是为什么您想知道这一切的全部意义。我建议你阅读一些关于 Java/Scala 上下文中的依赖注入的内容,这应该会弄清楚它是如何工作的,它解决了什么问题以及(缺点)优点是什么(既然你知道 Ruby,为什么在 Ruby 中不需要以同样的方式)。
Trying to implement the "DAO" object I have found almost impossible to
to inject the Play Application context without using Play.current
which is deprecated. That kind of deprecation and the absence of a way
of injecting the context (or at least I haven't found it) sounds
strange to me.
您应该能够简单地将应用程序上下文注入到您的 DAO 中,例如像这样:
class AdminDao @Inject()(val application : Application) {
然后您就可以使用该应用程序了。这相当于弃用的
val application = Play.current
在这两种情况下,您都捕获了 运行 Application
。它背后的依赖注入框架确保递归地解决依赖关系,即当你在控制器中依赖你的 DAO 时,它会指出 DAO 本身依赖于应用程序。它解析应用程序,将其注入到一个新的 DAO 实例中,最后将其注入到您的控制器中。
最后但并非最不重要的是,有很多方法可以像往常一样通向罗马:也许 ActiveSlick 是您认为有用的东西(免责声明:我自己还没有尝试过)。
我习惯于 Rails 上的 Ruby 或 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 以努力删除全局状态(有关为什么全局状态是坏事的讨论,请参阅 here for example):
Play now, out of the box, uses dependency injection provided by Guice. This is part of a long term strategy to remove global state out of Play, which we hope to complete in the Play 3.0 release.
因此,关于 Play 的正确方法是您的示例 1,使用对象并因此使用硬编码依赖项确实是不可取的,纯粹基于您反对游戏的事实(但是 DI 也有很多优点)。
我不太精通 Ruby,但据我所知,不需要 Java/Scala 中的带有框架(例如 Guice)的 DI,因为 Ruby具有某些语言功能来以不同的方式解决问题,这可能就是为什么您想知道这一切的全部意义。我建议你阅读一些关于 Java/Scala 上下文中的依赖注入的内容,这应该会弄清楚它是如何工作的,它解决了什么问题以及(缺点)优点是什么(既然你知道 Ruby,为什么在 Ruby 中不需要以同样的方式)。
Trying to implement the "DAO" object I have found almost impossible to to inject the Play Application context without using Play.current which is deprecated. That kind of deprecation and the absence of a way of injecting the context (or at least I haven't found it) sounds strange to me.
您应该能够简单地将应用程序上下文注入到您的 DAO 中,例如像这样:
class AdminDao @Inject()(val application : Application) {
然后您就可以使用该应用程序了。这相当于弃用的
val application = Play.current
在这两种情况下,您都捕获了 运行 Application
。它背后的依赖注入框架确保递归地解决依赖关系,即当你在控制器中依赖你的 DAO 时,它会指出 DAO 本身依赖于应用程序。它解析应用程序,将其注入到一个新的 DAO 实例中,最后将其注入到您的控制器中。
最后但并非最不重要的是,有很多方法可以像往常一样通向罗马:也许 ActiveSlick 是您认为有用的东西(免责声明:我自己还没有尝试过)。