Aggregates without public constructors


I would like to see some effort to remove the need for having public constructors in the aggregates. I do understand why they are there, but this is a framework that I would guess its mostly used by Domain Driven Design (and CQRS, ES) enthusiasts.

Aggregates have the purpose of protecting some invariants. They are mostly a state machine and controlling its state is hard if instances can be created in an invalid state.

I also know that there might not be another alternative except Reflection, but it would be nice to have the option to choose. This choice could be made by implementing an A or B interface or any other appropriate approach. Performance comparisons could help decision making.

An approach to this problem I saw in another language/framework (and it’s non-conventional), was to serialize the object, manipulate its values in the serialized form, and deserialize. The performance was drastically better than using the Reflection library. Since it was an internal thing nobody needs to know or care about, I thought it was a valid hacky way to achieve acceptable performance + code flexibility.

Fábio Carneiro

I have not experienced a requirement for public constructors in an aggregate. The aggregates I work with have either protected or package protected no argument constructors, or package protected constructors that accept a command as an argument.

Can you make them private?

Item 5 says:

I think it doesn’t have to be public, so you just try to make it private and see what happens. Maybe protected will do.
If you are using Kotlin you could create a synthetic no-argument constructor using Gradle or Maven plugin. That means that in the code there is no constructor, but you can actually call it with reflection. that’s what I am using and it’s very nice that way :slight_smile:

I also sign under that suggestion. It’s that little thing that could make code a bit cleaner :slight_smile:

private constructor works when instantiating the aggregate initially and saving its data but does not work when loading it again for the next state change.

This is the exception it throws when you try:

Hi Fabio,

If you wouldn’t be using the ‘axon-spring’ module, then I assume having a private constructor would’ve worked.
Axon Framework uses the ReflectionUtils as off release 0.7 to access fields but also adjust their modifier for use cases like this.

I think the request is fine by the way, but note that Axon Framework moved away from using interfaces to define an Aggregate class.
Note this was Axon Framework 2.x, in release 3.x and up this was changed to the current configuration and annotation paradigm.

Especially from a DDD perspective, you’d actually want zero framework code in there.
Thus in essence the annotations can already be regarded as dirty stuff - an interface thus too.

Concluding, feature suggestions are better placed on the framework’s GitHub page.
That gives the team at AxonIQ the chance to discuss the suggestion and a potential approach, and makes it’s progress and our decision on it visible for the entire user base.

Prior to adding such a feature request, check whether one already exists. I don’t believe there is one, but you never know.