Reusable Write Models

Hi,

I would like to hear about your experiences and approaches with resuable write models. As I am not sure that this is a common term, I explain first what I mean with this.

We use Axon aggregates to model our business processes. Some parts of these processes are often similar or even completely identical to each other. We want to avoid too much duplicated code - hence the reuse (or the sharing) of the write models. Currently we are aware of two approaches.

The first one is inheritance. We can move some code (including the command handlers) into an abstract base class. The events and commands on this level are shared. The concrete classes must only define the command handlers to initially create the aggregates and can modify or augment the behaviour of the base class. This works, but - due to the lack of multiple inheritance in Java - we can only have a single abstract class for each aggregate. That means we end up with a very generic abstract class containing only the very few elements that are identical to each process.

The second approach is to use compositions of write models. Let’s say we have aspects that are available in some of the processes but not in all. We move the code into an Axon entity, where we implement the command methods and the event sourcing handlers. However, we cannot define command handlers in such an entity, because as soon as it is used in two or more aggregates we would register the command handlers multiple times (because the command handlers are registered on level of the entity, not on the level of the concrete aggregate). Thus we define the commands for the concrete aggregates and delegate to the command methods of the entity. This works, but it means that we still have to define the commands multiple times for each concrete aggregate using this aspect.

Is there an approach to reusable write models that we are not aware of? Or an aspect to our approaches that we somehow missed?

Thank you and best regards

Nils

Hey Nils-Christian, nice to chat with you here as well :slight_smile:

Your breakdown on write-model reuse is correct.

Command handlers are in Axon Framework 4 not allowed to be registered twice. We view this as a hard requirement for consistent routing to an instance owning the command, essentially. Although I can envision combining the commandName with a write-model type would work, that is not what AF4 does at the moment. I can foresee that becoming trivial with our current developments in AF5, though. Sadly enough, that is not going to help you today, of course.

I do have another suggestion worth looking into. What about moving the business validation into a Domain Service? Potentially an implementation that returns the collection of events to apply as a result of validating. You would, of course, still hit the aforementioned “single command handler registration” barrier setup. But, perhaps it allows you a workable separation that fits your project.