Wanted to get a thread started on ideas for how this might work.
The problem generally is that our containers internalise construction, and
offer no way to parameterise it.
sourceSets {
custom {}
}
The use has no way of influencing what kind of thing “custom” is. The immediate
need for this kind of thing is with the publications container. The user needs
to be able to add arbitrary maven, ivy etc. publication objects.
Options:
1. Add via concrete types, with rigid constructor contract
To add something of a certain type, you specify the actual type, which must
have a 1 string arg constructor (the item name)…
publications {
custom(DefaultMavenPublication)
}
class DefaultMavenPublication implements MavenPublication {
DefaultMavenPublication(String name) { … }
}
2. Add via concrete types, allowing constructor params
publications {
custom(DefaultMavenPublication, arg1, arg2)
}
class DefaultMavenPublication implements MavenPublication {
DefaultMavenPublication(String name, Object arg1, Object arg2) { … } //
arg1 & arg2 could be typed of course
}
3. Add via contract types, using rigid factories…
publications.registerTypeFactory(new MavenPublicationFactory())
publications {
custom(MavenPublication) {}
}
class MavenPublicationFactory implements DomainObjectFactory<MavenPublication> {
MavenPublication createDomainObject(String name) {
instantiator.newInstance(DefaultMavenPublication, name)
}
}
(not suggesting that as the DomainObjectFactory API, just illustrative)
4. Add via contract types, allowing construction params…
publications.registerTypeFactory(new MavenPublicationFactory())
publications {
custom(MavenPublication) {}
}
class MavenPublicationFactory implements DomainObjectFactory<MavenPublication> {
MavenPublication createDomainObject(String name, Object...
constructionArgs) {
// constructionArgs doesn't necessarily need to be passed to
the constructor
instantiator.newInstance(DefaultMavenPublication, name,
*constructionArgs)
}
}
5. Add via contract types, using typed builders to parameterise
publications.registerTypeBuilder(MavenPublicationBuilder)
publications {
custom(MavenPublication, «configure the builder by map») {
someMethodOnMavenPublication()
}
}
publications.registerTypeBuilder(MavenPublicationBuilder)
publications {
custom MavenPublication), {
« configure builder by closure »
}, {
someMethodOnMavenPublication()
}
}
class MavenPublicationBuilder implements DomainObjectBuilder<MavenPublication> {
MavenPublicationBuilder(String domainObjectName, Instantiator
instantiator) { … }
MavenPublication build() {
instantiator.newInstance(DefaultMavenPublication, name)
}
}
I think option 3 is the most desirable, if we can avoid the need to
parameterise what gets created at construction time. 5 offers the most
flexibility, but I can't think of a way to avoid making the DSL so cumbersome
and to avoid the complexity.
Perhaps the two aren't mutually exclusive. We could start with 3, and then add
something like 5 later if it turns out to be necessary.
1 and 2 are non starters for me. There needs to be indirection between the
requested and concrete type.
I don't like 4 because it's so loose. There's no compile time typing and no
good way to specify the contract.
Given those options (feel free to propose others), I'd vote for starting with 3
I think.
--
Luke Daley
Principal Engineer, Gradleware
http://gradleware.com
---------------------------------------------------------------------
To unsubscribe from this list, please visit:
http://xircles.codehaus.org/manage_email