Gradle Goodness: Create Objects Using DSL With Domain Object Containers
Gradle offers the NamedDomainObjectContainer
class to create a collection of objects defined using a clean DSL. The only requirement for the objects we want to create is that they have a constructor that takes a String
argument and a name
property to identify the object. The value for the name
property must be unique within the collection of objects. We create a new instance of a NamedDomainObjectContainer
with the container
method of the Gradle Project
class. We can add the NamedDomainObjectContainer
instance to the extensions
property of our project
, so we can use a DSL to create instances of objects that need to be in the NamedDomainObjectContainer
object in our project.
The following code shows a simple build script in which we want to create a collection of Product
objects. The creation of the NamedDomainObjectContainer
object is done in a plugin so we only have to apply the plugin to use the DSL to create Product
objects:
apply plugin: ProductsPlugin
// DSL to define new objects of type Product.
products {
// Create Product with name pencil.
pencil {
price = 0.05
}
// Create Product with name crayon.
crayon {
price = 0.18
}
}
class ProductsPlugin implements Plugin {
void apply(final Project project) {
// Create NamedDomainObjectContainer instance for
// a collection of Product objects
NamedDomainObjectContainer productContainer =
project.container(Product)
// Add the container instance to our project
// with the name products.
project.extensions.add('products', productContainer)
// Simple task to show the Product objects
// that are created by Gradle using
// the DSL syntax in our build file.
project.task('reportProducts') << {
def products = project.extensions.getByName('products')
products.all {
// A Product instance is the delegate
// for this closure.
println "$name costs $price"
}
}
}
}
class Product {
// We need a name property
// so the object can be created
// by Gradle using a DSL.
String name
BigDecimal price
Product(final String name) {
this.name = name
}
}
We can run the reportProducts
task to see the name
and price
properties of the Product
instances:
$ gradle -q reportProducts
crayon costs 0.18
pencil costs 0.05
$
Written with Gradle 2.11.