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…
  1. Entita dědí z Entity a událost zaznamená metodou Raise.
  2. Událost implementuje IDomainEvent – má EventId (pro odhalení duplicit) a OccurredAtUtc.
  3. Při SaveChangesAsync ji ModuleDbContext uloží do outboxu; doručí ji worker.
  4. 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 – OrderService se 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).

Na internetu