Suppose I have a skeleton plugin that is deliberately intended to be subclassed to create concrete plugins. Something like
abstract class AbstractMyPlugin protected constructor(private val taskname: String) : Plugin<Project> {
protected abstract fun getCondition(project: Project): Provider<Boolean>
final override apply(project: Project) {
if (!project.tasks.names.contains("setup${taskname}")) {
throw GradleException()
}
project.tasks.named("setup${taskname}").configure {
val condition = getCondition(project)
onlyIf { condition.get() }
}
}
}
There is something that is off about its design, in that getCondition()
is meant to, but does not have to, return the same provider for every call with the same project passed in (ie. a de facto abstract val
).
Would a design that involves an abstract extension work in its place? Something like
abstract class MyPlugin<E : MyExtension> protected constructor(private val taskname: String) : Plugin<Project> {
protected abstract val extensionClass: Class<E>
final override apply(project: Project) {
val extension = project.extensions.getByType(extensionClass)
project.tasks.named("setup${taskname}").configure {
val condition = extension.getCondition()
onlyIf { condition.get() }
}
}
}