How to efficiently populate extra properties in the Gradle Kotlin DSL?

According the current (5.2.1) documentation:

All enhanced objects in Gradle’s domain model can hold extra user-defined properties. This includes, but is not limited to, projects, tasks, and source sets.

Extra properties can be added, read and set via the owning object’s extra property. Alternatively, they can be addressed via Kotlin delegated properties using by extra.

Here is an example of using extra properties on the Project and Task objects:

val kotlinVersion by extra { "1.3.21" }
val kotlinDslVersion by extra("1.1.3")
extra["isKotlinDsl"] = true

tasks.register("printExtProps") {
    extra["kotlinPositive"] = true

    doLast {
        // Extra properties defined on the Project object
        println("Kotlin version: $kotlinVersion")
        println("Kotlin DSL version: $kotlinDslVersion")
        println("Is Kotlin DSL: ${project.extra["isKotlinDsl"]}")
        // Extra properties defined on the Task object
        // this means the current Task
        println("Kotlin positive: ${this.extra["kotlinPositive"]}")
    }
}

You don't have to use delegation, just write extra.set("propertyName", "propertyValue"). You can do this with an apply block if you want:

extra.apply {
    set("propertyName", "propertyValue")
    set("propertyName2", "propertyValue2")
}