Can';无法访问项目';s Build.scala中的类/对象

Can';无法访问项目';s Build.scala中的类/对象,scala,playframework,playframework-2.2,Scala,Playframework,Playframework 2.2,我想创建类似Ruby rake的任务。我知道我可以通过sbt完成任务,但我不能使用项目中的任何类或对象。例如: # project/AppBuild.scala object AppBuild extends Build { //............ lazy val sampleTask = taskKey[Unit]("hello123", "A sample task.") := { val u = models.User.single(123) // Erro

我想创建类似Ruby rake的任务。我知道我可以通过sbt完成任务,但我不能使用项目中的任何类或对象。例如:

# project/AppBuild.scala
object AppBuild extends Build {
  //............
    lazy val sampleTask = taskKey[Unit]("hello123", "A sample task.") := {
      val u = models.User.single(123) // Error! models is not accessible
    }

}

所以我无法访问models.User或项目中的任何其他类。对此我能做些什么?

Build.scala定义了如何构建项目。在构建定义中,您试图使用应基于该定义构建的内容

一般的答案是,
模型
必须在之前构建(一个单独的模块),并作为构建项目的依赖项添加(而不是“真实”项目)


但是你需要从项目中得到一些东西来实际构建项目的想法听起来很可疑。如果你解释一下为什么要这样做,或者有人能给出更好的答案。

Scala是强类型的,所有类型都必须在编译时解析。您的构建文件是首先编译的-它不能依赖于它正在构建的项目的类型,因为要构建它正在构建的项目,它首先需要自己构建-请参见循环依赖

因此,不能简单地从构建文件中调用项目中的Scala代码

您可以在项目中定义一个主类,并告诉SBT使用
runMain
任务调用该类。这就完成了所有必要的工作,首先编译项目,然后创建一个具有所有必要依赖项的类加载器,然后反射式地查找主类并调用它。请注意,您的代码可能需要一个正在运行的应用程序,因此您最好在
test
文件夹中执行此操作,并使用Play的假应用程序助手,例如:

package foo.bar

import play.api.test._
object MyMainClass extends App {
  Helpers.running(FakeApplication()) {
    val u = models.User.single(123)
    ...
  }
}
现在从
播放
控制台,尝试以下操作:

test:runMain foo.bar.MyMainClass
如果这样做有效,那么您可以通过将其添加到
build.sbt
build.scala
中的生成设置来缩短它:

TaskKey[Unit]("do-something", "Do something") := {
  (runMain in Test).toTask("foo.bar.MyMainClass").value
}

然后你应该能够运行
做一些事情

这不是可疑的,我只是想能够在数据库中运行“sbt insertPredefinedUsers”。
作为构建项目的依赖项添加(而不是“真实”项目)
-构建项目和“真实”项目有什么不同项目?1)我认为在编译该项目的过程中,在数据库中插入与该项目相关的内容是非常不寻常的。2)在SBT中,结构是递归的。假设您在根目录中有一个项目。然后在/project子目录中有另一个项目,它定义了如何在根目录中构建“项目”。如果你愿意,你可以有一个/project/project来定义如何构建项目来构建项目。。。我的想法是将依赖项添加到/project目录中的构建项目中。1)它与编译有什么关系?“游戏控制台中的test:runMain foo.bar.MyMainClass”看起来不好,因为它与测试无关。实际上,看看这个——它是通过反射完成的,非常优雅。