Groovy - 如何反映来自另一个 groovy 应用程序的代码以在其中找到 Classes/Properties/Types

Groovy - How to reflect code from another groovy app to find Classes/Properties/Types within

首先,我有 .NET 背景,所以请原谅我缺乏 groovy 行话。当我在 .NET 商店时,我们使用 TypeScript 和 C# 来构建 Web 应用程序。在我们的控制器中,我们总是 receive/respond 使用 DTO(数据 xfer 对象)。每当你 create/modify 一个 DTO 时,你必须更新与之对应的 TypeScript 接口(d.ts 文件),这一定是一件令人头疼的事情。

所以我们创建了一个小应用程序(一个简单的 exe),它将 dll 从 webapp 加载到其中,然后反射它以找到 DTO(按特定名称空间过滤),并通过它们解析以找到每个 class 中的名称、它们的属性以及它们的属性的数据类型,将这些信息生成一个字符串,最后保存到一个 d.ts 文件中。

此应用随后在每次构建网站时都配置为 运行。这样,当您访问 run/debug/build 网站时,它会自动更新您的 d.ts 文件 - 这使得使用 TypeScript 变得更加容易。

长话短说,如果我要编写一个简单的 groovy 应用程序来生成我想要的 d.ts,我如何通过 Grails 网站实现这一点?

-- 或--

我如何将 IDE(ex IntelliJ)转换为 运行 生成这一代 post- 的 groovy 文件(即应用程序的一部分)构建?

我确实找到了这个,但仍然需要一种在编译时 运行 的方法:

Groovy property iteration

class Foo {
    def feck = "fe"
    def arse = "ar"
    def drink = "dr"    
}

class Foo2 {

    def feck = "fe2"
    def arse = "ar2"
    def drink = "dr2"
}


def f = new Foo()
def f2 = new Foo2()


f2.properties.each { prop, val ->
    if(prop in ["metaClass","class"]) return
    if(f.hasProperty(prop)) f[prop] = val
}

assert f.feck == "fe2"
assert f.arse == "ar2"
assert f.drink == "dr2"

我已经能够通过以下 Gant 脚本提取域对象及其 持久性 字段:

scripts/Props.groovy:

import static groovy.json.JsonOutput.*

includeTargets << grailsScript("_GrailsBootstrap")

target(props: "Lists persistent properties for each domain class") {
    depends(loadApp)

    def propMap = [:].withDefault { [] }
    grailsApp.domainClasses.each {
        it?.persistentProperties?.each { prop ->
            if (prop.hasProperty('name') && prop.name) {
                propMap[it.clazz.name] << ["${prop.name}": "${prop.getType()?.name}"]
            }
        }
    }
    // do any necessary file I/O here (just printing it now as an example)
    println prettyPrint(toJson(propMap))
}

setDefaultTarget(props)

这可以通过命令行 运行 像这样:

grails props

产生如下输出:

{
    "com.mycompany.User": [
        { "type": "java.lang.String" },
        { "username": "java.lang.String" },
        { "password": "java.lang.String" }
    ],
    "com.mycompany.Person": [
        { "name": "java.lang.String" },
        { "alive": "java.lang.Boolean" }
    ]
}

这种方法的几个缺点是我们没有获得任何瞬态属性,而且我不确定如何将其连接到 _Events.groovy eventCompileEnd 事件中。

谢谢凯文!只是想提一下,为了达到 运行,这里有一些我必须确保在我的案例中执行的步骤,我认为我会分享:

-> 打开grails BuildConfig.groovy

-> 将 tomcat 从构建更改为编译,如下所示:

plugins {
    compile ":tomcat:[version]"
}

-> 将您的 Props.groovy 放入根目录下的脚本文件夹中(注意 grails-app 文件夹的路径以供参考)

[application root]/scripts/Props.groovy
[application root]/grails-app

-> 打开终端

gvm use grails [version]
grails compile
grails Props

注意:我使用 Grails 2.3.11 进行 运行 的项目。

这让你脚本中的所有内容都对我来说 运行 成功了。现在修改println部分生成Typescript接口。

post 准备好后会 github link 所以一定要回来查看。