Gradle can only create specific types of properties on managed types个
这些是
Property<T>
个
RegularFileProperty
个
DirectoryProperty
个
ListProperty<T>
个
SetProperty<T>
个
MapProperty<K, V>
个
ConfigurableFileCollection
个
ConfigurableFileTree
个
DomainObjectSet<T>
个
NamedDomainObjectContainer<T>
个
在Gradle v8.2,将支持ExtensiblePolymorphicDomainObjectContainer<T>
.在此之前,必须使用ObjectFactory
手动创建它们.
实现这一点的一种方法是将ObtFactory注入构造函数:
import javax.inject.Inject
import org.gradle.api.*
imports org.gradle.kotlin.dsl.*
abstract class MyExtension @Inject constructor(
private val objects: ObjectFactory,
) {
val container: ExtensiblePolymorphicDomainObjectContainer<MyBaseClass> =
objects.polymorphicDomainObjectContainer()
}
Pro tip: Kotlin DSL accessors for NamedDomainObjectContainer
s
请注意,尽管Gradle会自动创建NamedDomainObjectContainer
个属性,但手动创建一个属性并将其作为扩展添加通常是个好主意.
abstract class MyExtension @Inject constructor(
private val objects: ObjectFactory,
) : ExtensionAware {
// *all* types that Gradle instantiates are automatically ExtensionAware,
// but adding the interface explicitly helps with IDE hints
val namedContainer: NamedDomainObjectContainer<MyBaseClass> =
objects.domainObjectContainer(MyBaseClass::class).also {
extensions.add("namedContainer", it)
}
}
这是冗长和奇怪的--所以为什么要麻烦呢?
通过添加namedContainer
作为扩展,Gradle将自动为添加的任何元素生成一些不错的type-safe Kotlin DSL accessors.
因此,如果在您的插件中添加了一个元素.
abstract class MyPlugin : Plugin<Project> {
override fun apply(project: Project) {
val extension = project.extensions.create<MyExtension>("myExtension")
extension.namedContainer.register("anElement") { ... }
}
}
在任何构建脚本中,都有一种以类型安全和IDE友好的方式访问元素的简单方法
// build.gradle.kts
plugins {
id("my.plugin")
}
myExtension {
namedContainer.anElement { // auto generated accessor
}
}