Avanade

coreex-command-publish-e2e

"Add the sending/publishing of a command to another domain end-to-end: adapter (interface + Infrastructure implementation + wire DTO), application-service call site (outbox vs direct broker), destination routing (NamedDestinationProvider -> per-domain queue), Service Bus topology in Test.Common, API/Relay tests, and Aspire E2E. USE FOR: a domain must instruct another domain to do something (a command, not an event) and the developer wants code, infrastructure, tests and Aspire in one guided workflow. DO NOT USE FOR: publishing an event (fire-and-forget; use coreex-app-service — events go to the shared topic), receiving a command (use coreex-command-subscribe-e2e), or a synchronous request/response call to another domain (use coreex-adapter with a typed HTTP client)."

Avanade 28 8 Updated 1w ago

Resources

1
GitHub

Install

npx skillscat add avanade/coreex/coreex-command-publish-e2e

Install via the SkillsCat registry.

SKILL.md

CoreEx: Publish a Command (End-to-End)

Guides you through making one domain send a command to another: the adapter that builds it, the transactional call site, the routing to the target's queue, the broker topology, the tests and the Aspire E2E — gathered in one interview so nothing is asked twice.

Events vs Commands — decide first

Event Command
Intent "This happened" — reactive, fire-and-forget "Do this" — addressed to one consumer
Built with EventData.CreateEventWith(...) EventData.CreateCommand("{target-domain}", "{entity}", "{action}")
Destination (NamedDestinationProvider) Shared topic (CoreEx:Events:Destination) — every domain subscribes Queue {Destination}-{target-domain} (e.g. contoso-products) — only the target sees it
Contract owner Publisher Target domain (DomainName = the owner of the message contract)

If the developer means an event, stop and use coreex-app-service — nothing on this page applies.

When to Use

  • "Shopping must tell Products to confirm the reservation" — a domain instructs another domain
  • A compensating command (cancel/undo) must be sent, possibly bypassing the outbox
  • The developer wants code + broker topology + tests + Aspire covered in one pass

When Not to Use

  • Publishing an event — coreex-app-service
  • Receiving/handling a command — coreex-command-subscribe-e2e
  • A synchronous call that needs an answer — coreex-adapter (typed HTTP client)

Workflow Overview

  1. Read Feature Configuration — messaging-provider must be ServiceBus; outbox-enabled decides outbox vs direct; rop-enabled decides Result<T> vs exceptions.
  2. Verify routing — AddNamedDestinationProvider() is registered in every host that publishes; migrate away from AddFixedDestinationProvider (it would send commands to the shared topic).
  3. Interview — target domain, command shape, payload, trigger, outbox vs direct, target location; one batched turn.
  4. Execute L1 sequence (table below).
  5. Topology + tests + Aspire — queue in Test.Common ServiceBus, API/Relay tests, coreex-aspire.
  6. Validate — build, unit/integration tests, report.

For full step-by-step guidance see `references/workflow.md`.

L1 Sequence

Step Skill Condition
1 `coreex-adapter` Always — the adapter interface + implementation that builds the EventData command; the wire DTO for a payload lives in Infrastructure/Clients/{Target}/
2 `coreex-app-service` Always — the call site inside _unitOfWork.TransactionAsync(...) (or the compensation path)
3 (inline — Service Bus topology) Always — add the queue to Test.Common ServiceBus.GetQueues()
4 `coreex-test-api` Always — assert the outbox row: destination queue, subject, key/value
5 `coreex-test-relay` Always — prove the relay delivers the command to the queue
6 `coreex-aspire` When an aspire/ folder exists — topology, consumer wiring, E2E

Key References