On 06/10/2011, at 6:32 PM, Adam Murdoch wrote: > On 06/10/2011, at 8:49 AM, Peter Niederwieser wrote: > >> To me the way forward seems clear: >> >> - Provide additional TaskContainer.add methods that add and configure a task >> atomically. E.g. TaskContainer.add(name, type, closure) >> >> - Guarantee that callbacks are only invoked after the task has been >> configured if an atomic add operation is used >> >> - Review plugins in the Gradle codebase to use atomic add operations >> whenever feasible > > I'd rather not do this. The problem cross cuts all types of domain objects, > so the solution should not be specific to tasks. > > Also, the whole point of the notifications is that the thing that creates the > domain object should not need to know which things need to know about it. > Having different versions of add() forces the creator to know this. Instead, > the creator should not have to care about who (if any) needs to know about > the domain object being added. > > One option is to add different types of notifications to > DomainObjectContainer, so you can be notified: > * when the object is created, so you can apply default values and convention > mappings
> * when the object is configured, so you can validate the configuration > * when the object is added to the container, so you can do something useful > with the configured object Do we want to go down this route of having the collections have more knowledge about the elements? I guess as long as we don't embed this in the base of the collections stuff it will still be possible to put any object in our collections. > The problem with the current approach, plus the suggested changes we've been > discussing, is that none of them really solve the laziness problem. Even > after the configure closure has completed, the domain object can still be > mutated, possibly later by some script, or some plugin, or from the > command-line, or by a task later in the build. > > Instead, I think a real solution will apply a lifecycle to each domain object > that is independent of which, if any, containers the domain object is added > to. For example, a domain object is: > 1. created > 2. configured > 3. locked, so that no mutations are possible > 4. validated > > Each of these lifecycle steps would have notifications associated with it, so > that you can do useful stuff at these points. This makes a lot of sense. It's probably going to complicate the collection hierarchy even more by adding specialisations that know about this kind of lifecycle for objects, but it's easy to see the value in this. -- Luke Daley Principal Engineer, Gradleware http://gradleware.com
