Repository: AxonFramework/AxonFramework

Issue #2399: Aggregate / Command Model Parameter Resolver
Created: 2022-09-27T09:46:03Z
Feature Description
Currently, accessing the aggregate through command dispatching has roughly two approaches:

Have an external Command Handler that invokes the Aggregate's Repository to load an instance and invoke an operation.
Have a Command Handling Aggregate directly, placing @CommandHandler annotated methods within the model.

We can perhaps simplify option 1, by allowing the Aggregate as a resolvable parameter.
That way, users can decide against an annotated command model (as DDD-purist would prefer), but still benefit from automatic model loading.
So, being able to resolve state needed in the command handler using annotation would be a nice thing to introduce.
When this state object is loaded from an asynchronous repository (like the new event sourcing repository in AF5), wait for the CompletableFuture to finish if the parameter is the actual state type.
Here's an example of what it could look like:
@CommandHandler
??? handle(
        RecruitCreature command,
        @CommandModel State state
) {
    return decide(command, state);
}

class State {
   String prop1; 
  
    @EventSourcingHandler
    void evolve(SomethingHappened event) {
        this.prop1 = event.prop1;
    }
}
Current Behaviour
A user needs to (1) use an annotated command model or (2) invoke the Repository to enter the aggregate that should perform a task.
Wanted Behaviour
Provide a means where users can have their aggregate as a resolved parameter.
Possible Workarounds
A user can build this themselves.

Duplicate issue #3284: `CommandModelParameterResolver` | Parameter resolver for entity state
Created: 2025-02-17T22:43:55Z
Feature Description
I want to be able to resolve state needed in the command handler using annotation.
If state is loaded from async repository, wait for the completable future.
Something like:
@CommandHandler
   ??? handle(
            RecruitCreature command,
            @CommandModel State state
    ) {
        return decide(command, state);
    }

class State {
   String prop1; 
  
  @EventSourcingHandler
    void evolve(SomethingHappened event) {
        this.prop1 = event.prop1;
    }
  
}
Current Behaviour
With the current state of AF5 implementation if someone wants to execute some command against an entity, needs to load the entity from the repository invoking it directly, and dealing with CompletableFuture API (like blow), it's not "developer friendly" approach.
private final AsyncRepository<RecruitCreature.TargetId, State> stateRepository;
private final EventGateway eventGateway;

@CommandHandler
??? handle(
       RecruitCreature command,
       ProcessingContext processingContext
) {
   return stateRepository.load(command.targetId(), processingContext)
           .thenApply(ManagedEntity::entity)
           .thenApply(state -> decide(command, state))
           .thenAccept(eventGateway::publish);
}
Wanted Behaviour
There is an CommandModelParameterResolver
Possible Workarounds
Work with the Repository directly in the command handler.

Closing comment (2025-02-18T12:04:19Z): Closing this issue as a duplicate of #2399.