Plugin extension with lazy properties

I try to build a plugin using the latest guidelines, with lazy properties.

In the current form, the script crashes on evaluation, with message:

Cannot set the value of read-only property 'logFolder' for object of type Target$Inject.

If I comment the line abstract Property<String> getLogFolder() and uncomment the next one, it works.
But now logFolder is no longer a lazy property.

What is the best way of creating such an extension?

Gradle version is 6.9.1, java is 8, language is Groovy.
The simplified code is below:

apply plugin: MyPlugin

abstract class Target {
    String name

    abstract Property<String> getLogFolder()
    // String logFolder

    Target(String name) {
        this.name = name
    }
}

abstract class MyExtension {
    abstract Property<String> getExtra()
    abstract NamedDomainObjectContainer<Target> targets

    MyExtension(NamedDomainObjectContainer<Target> targets) {
        this.targets = targets
    }

    def targets(Closure closure) {
        targets.configure(closure)
    }
}

class MyPlugin implements Plugin<Project> {

    void apply(Project project) {
        NamedDomainObjectContainer<Target> targetsContainer = project.container(Target)
        project.extensions.create("myx", MyExtension, targetsContainer)
    }
}



// test config
myx {
    extra = 'extra prop'

    targets {
        dev {
            logFolder = 'dev_folder'
        }

        prod {
            logFolder = 'prod_folder'
        }
    }
}

task show {
    doLast {
        println "extra is ${myx.extra.get()}; there are ${myx.targets.size()} targets"
        myx.targets.each { target ->
            println "    ${target.name} - ${target.logFolder}"
        }
    }
}

For each container property, Gradle automatically adds a block to the Groovy and Kotlin DSL that you can use to configure the contents of the container
Developing Custom Gradle Types

So if your extension has a getter that returns a container type Gradle will generate the appropriate dsl code.

abstract class MyExtension {
    abstract Property<String> getExtra()
    abstract NamedDomainObjectContainer<Target> getTargets()
}
class MyPlugin implements Plugin<Project> {
    void apply(Project project) {
        project.extensions.create("myx", MyExtension)
    }
}

It works, thank you!

If someone else needs it, the working script is here:

apply plugin: MyPlugin

abstract class Target {
    String name
    abstract Property<String> getLogFolder()

    Target(String name) {
        this.name = name
    }
}

abstract class MyExtension {
    abstract Property<String> getExtra()
    abstract NamedDomainObjectContainer<Target> getTargets()
}

class MyPlugin implements Plugin<Project> {

    void apply(Project project) {
        project.extensions.create("myx", MyExtension)
    }
}


// test config
myx {
    extra = 'extra prop'

    targets {
        dev {
            logFolder = 'dev_folder'
        }

        prod {
            logFolder = 'prod_folder'
        }
    }
}

task show {
    doLast {
        println "extra is ${myx.extra.get()}; there are ${myx.targets.size()} targets:"
        myx.targets.each { target ->
            println "    ${target.name} - ${target.logFolder.get()}"
        }
    }
}