# Dotnet messaging patterns Human Guide

## What This Is For
Durable messaging patterns for .NET event-driven architectures. It gives the agent a clearer input/output frame for dotnet messaging patterns: what context to ask for, what decisions to make, and what usable artifact to return.

Use this as a human-readable version of the Dotnet messaging patterns agent skill. It is meant for marketers, operators, founders, and other non-coders who want the workflow without reading agent-specific implementation instructions.

## When To Use This
- Use this when you need a repeatable process for dotnet messaging patterns.
- Use this when the task needs judgment, examples, constraints, or a clear output format rather than a one-off prompt.
- Use this when you want to hand an AI assistant enough context to produce a usable marketing artifact.

## When Not To Use This
- Do not use this when you only need a quick factual answer.
- Do not use this when the work depends on private data you cannot share with the assistant.
- Do not use this as a replacement for legal, compliance, financial, or medical review.

## What You Need Before Starting
- The goal or business outcome you want.
- The audience, customer segment, or market context.
- Any source material the assistant should respect, such as notes, briefs, examples, URLs, or brand guidance.
- Constraints such as tone, length, channel, deadline, region, or approval requirements.
- A clear definition of what a good final answer should look like.

## Step-By-Step Workflow
1. State the job clearly: "Use the Dotnet messaging patterns guide to help me with..."
2. Add context: audience, goal, offer, channel, source material, and constraints.
3. Ask the assistant to identify missing inputs before producing the final output.
4. Have the assistant follow the skill-specific guidance below.
5. Review the result against the final checklist and ask for revisions where needed.

## Skill-Specific Guidance
- **Azure Service Bus**: Use sessions (`RequiresSession = true`) to guarantee FIFO within a session ID (e.g., per customer)
- **RabbitMQ**: Use a single consumer per queue, or consistent-hash exchange to partition by key
- **MassTransit**: Configure `UseMessagePartitioner` for key-based ordering
- **Upserts** (`INSERT ... ON CONFLICT UPDATE`) instead of blind inserts
- **Conditional updates** (`UPDATE ... WHERE Status = 'Pending'`) instead of unconditional
- **Deterministic IDs** derived from message content instead of auto-generated
- **Do not forget to handle poison messages** -- always configure max delivery count and DLQ monitoring. Without these, a single bad message blocks the entire queue indefinitely.
- **Do not use in-memory saga persistence in production** -- saga state is lost on restart, leaving business processes in unknown states. Use Entity Framework, MongoDB, or Redis persistence.
- **Do not assume message ordering across partitions** -- competing consumers and topic subscriptions deliver messages out of order by default. Use sessions or partitioning when order matters.
- **Do not skip idempotency for at-least-once consumers** -- brokers may redeliver on timeout, network glitch, or consumer restart. Every consumer must handle duplicate messages safely.
- **Do not hardcode connection strings** -- use environment variables or Azure Key Vault references. For local development, use user secrets or `.env` files excluded from source control.
- [Azure Service Bus documentation](https://learn.microsoft.com/en-us/azure/service-bus-messaging/)

## Decision Points And Nuance
The original skill emphasizes: Messaging Fundamentals, Message Types, Delivery Guarantees, Publish/Subscribe, Azure Service Bus Topics, RabbitMQ Fanout Exchange, MassTransit Publish, Competing Consumers, Pattern, Azure Service Bus -- Scaling Consumers.

Use these questions to steer the work:
- What is the intended audience or buyer?
- What source material must be preserved?
- What should the assistant optimize for: clarity, persuasion, accuracy, speed, creativity, or conversion?
- What examples represent the desired quality bar?
- What should the assistant avoid?

## Common Mistakes
- **At-least-once with idempotent consumers** is the standard approach for durable messaging. True exactly-once requires distributed transactions (which most brokers do not support) or consumer-side deduplication.
- deadLetterErrorDescription: "Missing required field: CustomerId");
- | **Orchestration** | A saga/process manager directs each step | Complex flows, compensation needed, visibility required |
- **Do not forget to handle poison messages** -- always configure max delivery count and DLQ monitoring. Without these, a single bad message blocks the entire queue indefinitely.
- **Do not use in-memory saga persistence in production** -- saga state is lost on restart, leaving business processes in unknown states. Use Entity Framework, MongoDB, or Redis persistence.
- **Do not assume message ordering across partitions** -- competing consumers and topic subscriptions deliver messages out of order by default. Use sessions or partitioning when order matters.
- **Do not skip idempotency for at-least-once consumers** -- brokers may redeliver on timeout, network glitch, or consumer restart. Every consumer must handle duplicate messages safely.
- **Do not hardcode connection strings** -- use environment variables or Azure Key Vault references. For local development, use user secrets or `.env` files excluded from source control.

## Copy-And-Paste Prompt
```text
Use the Dotnet messaging patterns human guide.

My goal:
[Describe the business outcome]

Audience:
[Describe who this is for]

Context and source material:
[Paste notes, examples, links, or existing copy]

Constraints:
[Tone, length, channel, timeline, must-include items, must-avoid items]

Before producing the final output, ask me for any missing information that would materially improve the result.
```

## Final Checklist
- [ ] The output matches the original goal.
- [ ] The audience and context are reflected in the answer.
- [ ] Important constraints and source material were preserved.
- [ ] The assistant made the relevant decisions explicit.
- [ ] The final artifact is ready to use, review, or hand to the next person.

## Source
This guide was generated from the wshaddix/dotnet-skills skill entry for `dotnet-messaging-patterns`.

## Source Skill Notes
These notes preserve the nuance from the original skill. Use them as supporting reference when the workflow above feels too generic.

# dotnet-messaging-patterns

Durable messaging patterns for .NET event-driven architectures. Covers publish/subscribe, competing consumers, dead-letter queues, saga/process manager orchestration, and delivery guarantee strategies using Azure Service Bus, RabbitMQ, and MassTransit.

**Out of scope:** Background service lifecycle and `IHostedService` registration -- see [skill:dotnet-background-services]. Resilience pipelines and retry policies -- see [skill:dotnet-resilience]. JSON/binary serialization configuration -- see [skill:dotnet-serialization]. In-process producer/consumer queues with `Channel<T>` -- see [skill:dotnet-channels].

Cross-references: [skill:dotnet-background-services] for hosting message consumers, [skill:dotnet-resilience] for fault tolerance around message handlers, [skill:dotnet-serialization] for message envelope serialization, [skill:dotnet-channels] for in-process queuing patterns.

---

## Messaging Fundamentals

### Message Types

| Type | Purpose | Example |
|------|---------|---------|
| **Command** | Request an action (one recipient) | `PlaceOrder`, `ShipPackage` |
| **Event** | Notify something happened (many recipients) | `OrderPlaced`, `PaymentReceived` |
| **Document** | Transfer data between systems | `CustomerProfile`, `ProductCatalog` |

Commands are sent to a specific queue; events are published to a topic/exchange and delivered to all subscribers. This distinction drives the choice between point-to-point and pub/sub topologies.

### Delivery Guarantees

| Guarantee | Behavior | Implementation |
|-----------|----------|----------------|
| **At-most-once** | Fire and forget; message may be lost | No ack, no retry |
| **At-least-once** | Message retried until acknowledged; duplicates possible | Ack after processing + retry on failure |
| **Exactly-once** | Each message processed exactly once | At-least-once + idempotent consumer |

**At-least-once with idempotent consumers** is the standard approach for durable messaging. True exactly-once requires distributed transactions (which most brokers do not support) or consumer-side deduplication.

---

## Publish/Subscribe

### Azure Service Bus Topics

```csharp
// Publisher -- send event to a topic
await using var client = new ServiceBusClient(connectionString);
await using var sender = client.CreateSender("order-events");

var message = new ServiceBusMessage(
    JsonSerializer.SerializeToUtf8Bytes(new OrderPlaced(orderId, total)))
{
    Subject = nameof(OrderPlaced),
    ContentType = "application/json",
    MessageId = Guid.NewGuid().ToString()
};

await sender.SendMessageAsync(message, cancellationToken);
```

```csharp
// Subscriber -- process events from a subscription
await using var processor = client.CreateProcessor(
    topicName: "order-events",
    subscriptionName: "billing-service",
    new ServiceBusProcessorOptions
    {
        MaxConcurrentCalls = 10,
        AutoCompleteMessages = false
    });

processor.ProcessMessageAsync += async args =>
{
    var body = args.Message.Body.ToObjectFromJson<OrderPlaced>();
    await HandleOrderPlacedAsync(body);
    await args.CompleteMessageAsync(args.Message);
};

processor.ProcessErrorAsync += args =>
{
    logger.LogError(args.Exception, "Error processing message");
    return Task.CompletedTask;
};

await processor.StartProcessingAsync(cancellationToken);
```
