Doménové události
Entita oznámí business fakt („objednávka byla potvrzena“) a handlery na něj nezávisle reagují.
Na této stránce
V jedné větě: Doménová událost je fakt v minulém čase, který vznikne uvnitř entity při změně jejího stavu –
OrderPlaced,OrderConfirmed,ProductChanged.
K čemu slouží
Entita Order ví nejlíp, kdy se stalo něco důležitého (potvrzení, zrušení). Místo aby sama volala sklad nebo
e-mail, jen to oznámí. Kdo chce reagovat, napíše handler. Entita ani OrderService o handlerech nevědí.
Přirovnání: Porodnice nevolá matrice, pojišťovně a babičce. Vystaví rodný list (událost) a každý, kdo ho potřebuje, si ho vyzvedne.
Jak to funguje v MiniShopu
sequenceDiagram
participant S as OrderService
participant O as Order (entita)
participant DB as OrderingDbContext
participant W as OutboxWorker
participant H as Handlery
S->>O: order.Confirm(now)
O->>O: Raise(new OrderConfirmed(...))<br/>událost jen leží v DomainEvents
S->>DB: SaveChangesAsync()
DB->>DB: uloží objednávku + událost do outboxu<br/>(jedna transakce)
Note over W: o chvilku později (≤ 2 s)
W->>H: OrderConfirmed → SendOrderConfirmationHandler, log…
- Entita dědí z Entity a událost zaznamená metodou
Raise. - Událost implementuje IDomainEvent – má
EventId(pro odhalení duplicit) aOccurredAtUtc. - Při
SaveChangesAsyncji ModuleDbContext uloží do outboxu; doručí ji worker. - Handler implementuje IDomainEventHandler<T>
a registruje se přes
AddDomainEventHandler<TEvent, THandler>().
Všechny doménové události
| Doménová událost | Modul (namespace) |
|---|---|
ProductChanged |
MiniShop.Domain.Inventory.Events |
ProductRemoved |
MiniShop.Domain.Inventory.Events |
StockAvailabilityChanged |
MiniShop.Domain.Inventory.Events |
OrderCancelled |
MiniShop.Domain.Orders.Events |
OrderCompleted |
MiniShop.Domain.Orders.Events |
OrderConfirmed |
MiniShop.Domain.Orders.Events |
OrderPackingStarted |
MiniShop.Domain.Orders.Events |
OrderPlaced |
MiniShop.Domain.Orders.Events |
OrderRejected |
MiniShop.Domain.Orders.Events |
OrderShipped |
MiniShop.Domain.Orders.Events |
Tabulka je vygenerovaná z kódu (MiniShop.Domain) při zobrazení stránky.
Události Orderingu jdou přes outbox k handlerům. Události Inventory (ProductChanged, ProductRemoved a od e-shop kroku 2
StockAvailabilityChanged – jen při změně pásma dostupnosti) se při uložení rovnou převedou na
integrační zprávy (sklad nemá vlastní doménové handlery).
Doménová vs. integrační událost
Doménová (OrderConfirmed) |
Integrační (OrderPlacedV1) |
|
|---|---|---|
| Kdo ji vidí | jen vlastní modul | kdokoli – jiné moduly a služby |
| Obsah | může nést celou entitu | jen data, žádné třídy domény |
| Smí se měnit | ano, kdykoli | ne – změna = nová verze V2 |
Proč takhle
- Odstranění vazeb –
OrderServicese nemění, když přibude další reakce. Viz SOLID. - Business jazyk – v kódu jsou vidět fakta, o kterých mluví i zákazník („objednávka byla zamítnuta“).
- Událost se nepošle hned, ale uloží – kdyby handler spadl, neztratí se (viz Outbox).