Gradle扩展为Closure的NamedDomainObjectContainer

时间:2015-12-06 17:14:26

标签: gradle gradle-plugin

我正在尝试构建一个允许以下内容的Gradle插件:

myPluginConfig {
    something1 {
        // this is a closure
    }
    somethingElse {
        // this is another closure
    }
    // more closures here
}

要实现这一点,我确定我需要使用NamedDomainObjectContainer来打包Closure集合,因此我设置了以下插件:

class SwitchDependenciesPlugin implements Plugin<Project> {
    void apply(Project project) {
        // add the extension
        project.getExtensions().myPluginConfig = project.container(Closure)
        // read the current configuration
        NamedDomainObjectContainer<Closure> config = project.myPluginConfig
        // test it out, always returns []
        System.out.println(config)
    }
}

我做错了什么,我需要使用project.extensions.create吗?如果是这样,怎么样?

编辑:我的用例包括根据项目层次结构中定义的某些变量添加依赖项。例如,如果在red上定义变量red,则以下配置将添加project.ext项目,否则将gson添加:{/ p>

myPluginConfig {
    redTrue {
        compile project(':red')
    }
    redFalse {
        compile 'com.google.code.gson:gson:2.4'
    }
    greenTrue {
        compile project(':green')
    }
}

对于此用例,我需要为myPluginConfig提供动态名称,因此需要MapNamedDomainObjectContainer

2 个答案:

答案 0 :(得分:1)

你能详细说明你在这里建模的内容吗?我认为你有两种选择。一种是使用NamedDomainObjectContainer。在这里你需要一个代表“某事”的类。在用户指南的示例中查看有关维护多个域对象的Gradle用户指南章节(请参阅https://docs.gradle.org/current/userguide/custom_plugins.html#N175CF),“事物”是“预订”。上面描述的内置配置语法是免费的。

如果你想拥有上面这样的语法而不需要维护多个域对象,你可以简单地添加一个方法,将Closure作为参数传递给Extension类:

void somethingToConfigure(Closure) {
}

答案 1 :(得分:0)

您不能将Closure作为NamedDomainObjectContainer的类型,因为您使用的类型必须具有名为name的属性和具有单个String参数的公共构造函数。

要解决此问题,您可以在Closure周围创建一个包装,并添加name字段。