@Service injection into aggregates?

vab2048

I have an Order aggregate with the following commands:

  • CreateOrderCommand
  • PlaceOrderCommand
  • ... (rest redacted as they are not pertinent to the question) ...

The PlaceOrderCommand refers to placing the Order onto an external execution venue. I have captured the behaviour for placing an order onto an external execution venue within a separate (non CQRS) @Service. However, I am struggling (due to lack of experience with Axon) with how best to connect my @Service with the aggregate.

My normal way of thinking would have me:

  • Inject the @Service into the aggregate's @Autowired constructor.
  • When the PlaceOrderCommand is issued, use the service to place the order onto the relevant execution venue and once done emit an event (either OrderPlacedSuccessfullyEvent or ErrorInOrderPlacementEvent).
  • Change the aggregate's state within the relevant @EventSourcingHandler.

My question is:

  • does my description above of how to handle this particular use case with Axon make sense (in particular injecting a @Service into an aggregate feels a bit off to me)?
  • Or is there a different best practice of how to model my scenario when using CQRS/event sourcing with Axon?
  • Axon requires an empty constructor in the aggregate. How does this reconcile with having the @Autowired constructor?

The other thing I was potentially considering was:

  • having a PlaceOrderInstructionCommand (instead of the simple PlaceOrderCommand) which emits a ReceivedPlaceOrderInstructionEvent that a separate event listener is listening for.
  • that event listener would have the relevant @Service injected into it and would do the placement of the Order.
  • then after placing the Order it would send a command (or should it emit an event?) to the aggregate informing it to update its state.

Could you please advise on what is best practice for modelling this scenario?

Ankit Vijay

The PlaceOrderCommand refers to placing the Order onto an external execution venue.

I'm assuming that placing the Order to an external execution venue means interacting with an external system. If yes, then it is should not be part of your domain. In that case, you would need to raise an Integration Event.

As you mentioned, you could raise a Command like ProcessOrder from your Domain. Within that Command, you can update your Domain (eg, set the OrderStatus to Processing) and raise an integration event like OrderArrived which is then handled by a separate process.

From Microsoft Docs:

The purpose of integration events is to propagate committed transactions and updates to additional subsystems, whether they are other microservices, Bounded Contexts or even external applications.

Integration events must be based on asynchronous communication between multiple microservices (other Bounded Contexts) or even external systems/applications.

You would handle that integration event as a separate process (or worker) outside of your Domain. This is where your@Service would be injected. Once, the order is processed successfully you can then broadcast integration event called OrderPlaced.

Now, any subscriber which has anything to do with placing the order would subscribe to the event. In your case, your Domain is interested in updating the state once the order is placed. Hence, you would would Subscribe to OrderPlaced event within your Domain to update the status of the Order.

Hope it helps.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

TOP Ranking

HotTag

Archive