AbstractNamedDomainObjectContainer.create

I’m using a DefaultNamedDomainObjectSet in my plugin and I’d like to add a all(Closure) call to execute something against all objects added to the set. The problem is that the Closure passed into the all method is being run before configure closure used to configure the object being added to the DefaultNamedDomainObjectSet. E.g.

def container = project.container(CustomArtifact)
container.all {
    println "Happens 1st"
    // No idea what object will look like after configure at this point
}
project.extensions.custom = container
  project {
    custom {
        'artifact' {
            println 'Happens 2nd'
        }
     }
}

I really want to act upon objects going into the container immediately as they’re being added, yet I require them being configured first. It’s evident in AbstractNamedDomainObjectContainer.create that it adds the object (triggering the DefaultDomainObjectCollection.doAdd call backs) THEN configures it. Personally, I feel that this is broken, the concept of configure hints that it’s being configured immediately after the constructor. If this is the intended behavior, then the problem becomes that I don’t have a hook to see objects after they’re configured until I actually go to act on the container’s contents. Or am I missing something?

That’s indeed how it works, you get the notification before the object is configured.

There’s no “configured” hook because there’s no real way of knowing when something is configured. The user is free to mutate the object at any time so running some code after the first “configure” call is a somewhat arbitrary.

Convention mappings are intended to deal with this because they allow you to derive values in a live way. They have their own issues, but work for a reasonably large class of problems.

What are you trying to do in such a post configure hook?

Thanks for the answer. I hadn’t really thought through users configuring the objects themselves at a later time, since they are using it to declaratively say what they want I didn’t expect them to alter it later.

For my use-case, I was trying to set some variables to default values incase the user left them out, but their default values are dependent on what fields the user did set, e.g I can use the name of the object to derive better defaults.

The name is known at creation time, so that will be there.