This message was deleted.
# community-support
s
This message was deleted.
a
Here's my extension, with a polymorphic container:
Copy code
abstract class MyPluginExtension @Inject constructor(
  objects: ObjectFactory
) {
  val userProvidedConfig: ExtensiblePolymorphicDomainObjectContainer<UserProvidedConfig> =
    objects.polymorphicDomainObjectContainer(UserProvidedConfig::class)
}
And here's some simple user-provided data that I want to capture. It's just a string property, that gets encoded later on. Users could provide their own subclass of
UserProvidedConfig
if they needed.
Copy code
abstract class UserProvidedConfig @Inject constructor (
  private val configId: String
): Named {
  abstract fun encode(): String

  override fun getName(): String = configId
}

abstract class StringConfig : UserProvidedConfig("string-config") {

  @get:Input
  abstract val someValue: Property<String>

  override fun encode(): String = someValue.orNull.toString()
}
So I create the extension, and register the
NamedDomainObjectFactory
for the subclass
Copy code
val myExtension = extensions.create<MyPluginExtension>("myExtension").apply {
  userProvidedConfig.registerFactory(StringConfig::class.java) { objects.newInstance() }
}
Now, I want to re-use this data in a task. It also has a
ExtensiblePolymorphicDomainObjectContainer
Copy code
abstract class MyTask @Inject constructor(
  objects: ObjectFactory,
) : DefaultTask() {
  val userProvidedConfig: ExtensiblePolymorphicDomainObjectContainer<UserProvidedConfig> =
    objects.polymorphicDomainObjectContainer(UserProvidedConfig::class)
}
But the problem is when I try to register the task, I want to re-use the values from the extension.
Copy code
val myTask = tasks.register<MyTask>("myTask") {

  // re-use the extension values
  userProvidedConfig.addAllLater(provider { myExtension.userProvidedConfig })
}
But this leads to an error:
this type is not known to this container. Known types are: (None)
I've tried accessing the createable types using the internal Gradle API, but I can't figure out how to do this type-safely
Copy code
val createableTypes =
    (myExtension.userProvidedConfig as org.gradle.api.internal.DefaultPolymorphicDomainObjectContainer<UserProvidedConfig>).createableTypes

  createableTypes.forEach { createableType ->
    userProvidedConfig.registerFactory( 
// ERROR None of the following functions can be called with the arguments supplied.
      createableType,
      NamedDomainObjectFactory { name ->
        myExtension.userProvidedConfig
          .containerWithType(createableType)
          .create(name)
      }
    )
  }
v
Couldn't you just set the container, instead of using
addAllLater
?
a
What do you mean, set the container? I dont think there's a
.set()
function
v
Copy code
abstract class MyTask @Inject constructor(
  objects: ObjectFactory,
  userProvidedConfig: ExtensiblePolymorphicDomainObjectContainer<UserProvidedConfig>
) : DefaultTask() {
  val userProvidedConfig = userProvidedConfig
}
a
ahh in the constructor. That could work… I’ll have a look, thanks. It would be more convenient to be able to copy a
ExtensiblePolymorphicDomainObjectContainer
instance, because then it means tasks could be registered arbitrarily, without needing the container. But that’s probably rare in my case.
my usecase is actually a little more complicated. I have a NamedDomainObjectContainer, and each element in that container also needs the ExtensiblePolymorphicDomainObjectContainer. Do you know if a NamedDomainObjectContainer supports creating an element and passing in constructor arguments? I couldn't find anything.
v
Yes, you can give a factory to
ObjectFactory.domainObjectContainer()
a
thanks! That helped. I'm pretty sure it's working, finally 😭 https://github.com/adamko-dev/dokkatoo/pull/36/files
👌 1