This message was deleted.
# community-support
s
This message was deleted.
t
You mean
ExtensiblePolymorphicDomainObjectContainer
? I don't think we can use plain
PolymorphicDomainObjectContainer
without using internal classes.
v
Then maybe that. What I need is a container where I can register different domain object types. Practically like
tasks
or
repositories
, so like
Copy code
foo {
    create<A>("a") {
        // configure a
    }
    create<B>("b") {
        // configure b
    }
}
Or in the end probably
Copy code
foo {
    a("a") {
        // configure a
    }
    b("b") {
        // configure b
    }
}
In the meantime I think I got something working, at least it compiles. Just not sure whether it is the proper way to go. I initially hoped it would be as simple as
Copy code
interface ConfigureNexusExtension {
    val foo: PolymorphicDomainObjectContainer<BaseOfAAndB>
}
but it seems not to be.
Not sure it's possible to have the
a("a") { … }
syntax though (not without Kotlin/Groovy extensions)
v
That's a method, not an example. As far as my experiments have shown there is more to it. The domain object must explicitly be
Named
, you need to register the types manually, ... Or I do it completely wrong
Don't care about that convenience syntax, I'll probably just make an extension function, it is an internal thing anyway, nothing that needs to be broadly compatible.
r
there's little integ test coverage on plain usage for this. this seems the little most reasonable integ test I've found: https://github.com/gradle/gradle/blob/327f679c0536453af0e953511e6e7f6397a4f76d/sub[…]g/gradle/api/internal/model/ObjectFactoryIntegrationTest.groovy
but indeed the ReportingExtension usage seems a good example and uses public api around polymorphic containers
v
ReportingExtension
usage is even newly added, just with 7.4 with the report aggregation changes. But I still don't fully grasp it. If I just do
Copy code
val foo = objects.polymorphicDomainObjectContainer(BaseOfAAndB::class)
like is shown in those examples, I get
Copy code
org.gradle.api.InvalidUserDataException: Cannot create a MavenRepository because this type is not known to this container. Known types are: (None)
[...]
Caused by: org.gradle.api.internal.NoFactoryRegisteredForTypeException
[...]
Instead I have to do
Copy code
val foo = objects.polymorphicDomainObjectContainer(BaseOfAAndB::class).apply {
    registerBinding(A::class, A::class)
    registerBinding(B::class, B::class)
}
to make it work. 😕
And that seems veeery unhandy for the convenience Gradle is usually providing
I was never able to get the generic
name(type)
syntax to work though
As part of an answer to an unrelated question on the forums, someone had mentioned the ability to register a Class reference as an extension which helps reference it by short name. Maybe if I had comined that here my attempts would have worked. Something like:
Copy code
project.getExtensions().add( "SpecialType", SpecialType.class );
// or
project.getExtensions().add( "SpecialType", SpecialType.class.getName() );
I wonder if that is what my attempts here missed. Anyway, aside from that particular form not working that project successfully uses such a container
v
Besides that the
name(type)
form should probably simply work from Groovy DSL if you import the type class, or do the extensions trick so that it looks like it were auto-imported (should be the first form for the extensions trick, as you need the class instance as argument, not the name), where in the linked code is the container used? I'm probably just blind.
s
used as in within the plugin? or as in used in a build file?
you probably mean in the build file... i exposed builder methods
"extension" e.g.
actually looking at it more (sorry its been years since i played with that code) it really more exposes an api around the container
i do expose the container itself in the dsl so i could play with it
the referencing of the class was problematic is all i remember, not the details of why
it did not help that the things i want to contain are naturally called extensions. so that naming quickly kept getting in the way also
i just used wrapping (composition) instead of inheritence for the container object
v
Yeah, had a deeper look. Thanks, but I don't think your example is good for a simple case. You do many custom stuff and
methodMissing
and so on and compose the container and so on. And additionally you use custom factories which I don't need, all the domain objects for me can directly be created that's why
registerBinding
is enough for me. But in the examples the other showed in the Gradle sources even that is not necessary but just works and I wonder why. 😕
s
Too bad.
t
AFAICT, uses in Gradle all use
registerBinding
or
registerFactory
.
s
Yes,
methodMissing
is very much Groovy. IIRC you use exclusively Kotlin
v
I know
methodMissing
and it is maybe appropriate there. If you would be in the container directly, it shouldn't be necessary as Gradle should provide the necessary magic for
newName(Type) { ... }
iirc. But yes, I use Kotlin DSL wherever possible. But if I would develop something for publishing, I'd make it convenient for both DSLs too of course.
AFAICT, uses in Gradle all use
registerBinding
or
registerFactory
.
Ah, yeah, didn't look right. Probably too tired yesterday. And because it's too scattered in the Gradle sources. 😄 The extensions just create the container and then some more specific plugins like
JacocoReportAggregationPlugin
or
JvmTestSuites
register the bindings.
Also in Gradle everything is an interface and has an implementation, so it is absolutely necessary there anyway. In my case I don't have implementations, I let Gradle directly implement the interface so there it seems to be a bit too verbose to being forced to do
Copy code
val foo = objects.polymorphicDomainObjectContainer(Base::class).apply {
    registerBinding(A::class, A::class)
    registerBinding(B::class, B::class)
}
but that indeed seems to be the way to go.
Thanks guys, but there should definitely be some documentation added about polymorphic containers. The only things I found were a two sentence mention in the manual and the DSL docs.
👍 1