Sto cercando di modellare una transazione commerciale che opera su due aggregati. Diciamo che abbiamo un tipo di aggregazione Bag che contiene elementi (entità). Mi piacerebbe avere un comando TransferItemToBag (itemName: String, fromBag: BagId, toBag: BagId) che estrae un oggetto dal primo Bag e lo mette al secondo. Quando viene ricevuto questo comando, voglio inviare un comando AddItemToBag (...) al secondo sacchetto e quando risponde con ItemAddedToBag (...) invia RemoveItemFromBag (...).
In altre parole, mi piacerebbe creare un comando nel sistema che faccia ciò che l'utente può fare con gli altri due comandi, inviandoli uno per uno. Pseudocodice:
on(FirstSecondCombinedCommand cmd) {
eventBus.register(eventType=FirstEvent, {
aggregate = repository.ofId(cmd.id2)
aggregate.handle(SecondCommand(...))
})
aggregate = repository.ofId(cmd.id1)
aggregate.handle(FirstCommand(...)) // produces FirstEvent
}
A chi appartiene questa logica? Si prega di notare che non voglio avere una consistenza strong, piuttosto quella finale. Sto anche bene se la transazione è interrotta perché c'era un diverso comando in competizione tra quello che arrivava a uno degli aggregati. Ho preso in considerazione diverse possibilità:
- Aggregato - il comando riguarda solo un singolo tipo di aggregazione, quindi la regola empirica per la scelta di un luogo per una logica di business (servizio aggregato / entità vs dominio) mi suggerisce di andare con quello. D'altra parte significa che il gestore di comandi nell'aggregato deve essere in grado di produrre comandi. Può violare una regola di singola mutazione aggregata all'interno di una transazione / comando, ma cosa accadrebbe se fosse eseguita in modo asincrono per evitarlo? Intendo postare il comando su una sorta di Command Bus e lasciarlo spedire in seguito, magari con un thread diverso.
- Saga - la situazione è in realtà una sorta di (lungo) processo in corso e questo mi ha fatto pensare a Sagas per l'implementazione. D'altra parte ho sempre considerato Sagas come qualcosa di stato. Non vedo uno stato esplicito nella mia situazione.
- Application Service - Ho visto in IDDD che è un posto dove impostare gli ascoltatori e invocare vari comandi, ma la situazione che sto descrivendo fa parte di una logica di business per me e vorrei mantenerla nel dominio .
- Domain Service - l'ultima possibilità a cui riesco a pensare. Sembra essere un posto ragionevole per cose interglobettotype, ma cosa succede se abbiamo lo stesso tipo di aggregazione?
Per favore non concentrarti su questo esempio concreto di aggregati (è stato ideato). Sono interessato a una risposta generica in cui inserire tale codice "transazione".