Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions website/src/docs/docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -2866,11 +2866,11 @@
"title": "Mocha",
"description": "Messaging Bus for .NET",
"metaDescription": "Mocha is a messaging framework for .NET that combines simplicity, flexibility, and observability with deep Nitro integration.",
"latestStableVersion": "v1",
"latestStableVersion": "v16",
"versions": [
{
"path": "v1",
"title": "v1",
"path": "v16",
"title": "v16",
"items": [
{
"path": "index",
Comment on lines 2866 to 2876
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Mocha uses a Roslyn source generator to validate your message handlers, consumer

# Mediator diagnostics

These diagnostics apply to the in-process [mediator](/docs/mocha/v1/mediator) - commands, queries, and notifications dispatched within a single process.
These diagnostics apply to the in-process [mediator](/docs/mocha/v16/mediator) - commands, queries, and notifications dispatched within a single process.

## MO0001

Expand Down Expand Up @@ -129,7 +129,7 @@ public class PlaceOrderHandler : ICommandHandler<PlaceOrder>

### Cause

A class implements a [handler](/docs/mocha/v1/handlers-and-consumers) interface (`ICommandHandler`, `IQueryHandler`, or `INotificationHandler`) but is declared `abstract`. The source generator skips abstract types because they cannot be instantiated.
A class implements a [handler](/docs/mocha/v16/handlers-and-consumers) interface (`ICommandHandler`, `IQueryHandler`, or `INotificationHandler`) but is declared `abstract`. The source generator skips abstract types because they cannot be instantiated.

### Example

Expand Down Expand Up @@ -259,7 +259,7 @@ public class GetOrderHandler : IQueryHandler<GetOrder, Order>

# Messaging diagnostics

These diagnostics apply to the [message bus](/docs/mocha/v1/handlers-and-consumers) - event handlers, request handlers, batch handlers, consumers, and sagas that communicate across service boundaries.
These diagnostics apply to the [message bus](/docs/mocha/v16/handlers-and-consumers) - event handlers, request handlers, batch handlers, consumers, and sagas that communicate across service boundaries.

## MO0011

Expand All @@ -272,7 +272,7 @@ These diagnostics apply to the [message bus](/docs/mocha/v1/handlers-and-consume

### Cause

A request type (used with `SendAsync` or `RequestAsync`) has more than one [handler](/docs/mocha/v1/handlers-and-consumers) implementation. Request types require exactly one handler - the bus cannot route to multiple targets.
A request type (used with `SendAsync` or `RequestAsync`) has more than one [handler](/docs/mocha/v16/handlers-and-consumers) implementation. Request types require exactly one handler - the bus cannot route to multiple targets.

### Example

Expand Down Expand Up @@ -376,7 +376,7 @@ public class OrderPlacedHandler : IEventHandler<OrderPlaced>

### Cause

A class implements a messaging [handler](/docs/mocha/v1/handlers-and-consumers) interface but is declared `abstract`. The source generator skips abstract types because they cannot be instantiated.
A class implements a messaging [handler](/docs/mocha/v16/handlers-and-consumers) interface but is declared `abstract`. The source generator skips abstract types because they cannot be instantiated.

### Example

Expand Down Expand Up @@ -423,7 +423,7 @@ public class OrderPlacedHandler : IEventHandler<OrderPlaced>

### Cause

A [`Saga<TState>`](/docs/mocha/v1/sagas) subclass does not have a public parameterless constructor. The saga infrastructure requires this constructor to instantiate the saga type. This is enforced by the `new()` constraint on the `AddSaga<T>` registration method.
A [`Saga<TState>`](/docs/mocha/v16/sagas) subclass does not have a public parameterless constructor. The saga infrastructure requires this constructor to instantiate the saga type. This is enforced by the `new()` constraint on the `AddSaga<T>` registration method.

### Example

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ The generator discovers these types:
| `IConsumer<T>` | Low-level consumer |
| `Saga<TState>` | Saga orchestration |

If you have used the [Mediator source generator](/docs/mocha/v1/mediator), this works the same way. The mediator generates `Add{ModuleName}()` on `IMediatorHostBuilder`; the message bus generates `Add{ModuleName}()` on `IMessageBusHostBuilder`.
If you have used the [Mediator source generator](/docs/mocha/v16/mediator), this works the same way. The mediator generates `Add{ModuleName}()` on `IMediatorHostBuilder`; the message bus generates `Add{ModuleName}()` on `IMessageBusHostBuilder`.

> **Recommendation:** Always use the source generator for handler registration. The generated code uses optimized, reflection-free registration paths. The source-generated output is designed for long-term stability across versions. Manual registration methods are available for edge cases but their internal behavior may change between releases.

Expand Down Expand Up @@ -91,15 +91,15 @@ If IntelliSense does not show `Add{ModuleName}()`:

- Confirm the `Mocha.Analyzers` package is referenced with `OutputItemType="Analyzer"` in your `.csproj`
- Rebuild the project - source generators run during compilation
- Check the build output for [analyzer diagnostics](/docs/mocha/v1/diagnostics) prefixed with `MO`
- Check the build output for [analyzer diagnostics](/docs/mocha/v16/diagnostics) prefixed with `MO`
- Verify you have at least one concrete handler class in the assembly

## Handler is not being called

If the source-generated method is available but a specific handler does not run:

- Check for [**MO0013**](/docs/mocha/v1/diagnostics#mo0013) (abstract handler) - only concrete classes are registered
- Check for [**MO0012**](/docs/mocha/v1/diagnostics#mo0012) (open generic) - close the generic type
- Check for [**MO0013**](/docs/mocha/v16/diagnostics#mo0013) (abstract handler) - only concrete classes are registered
- Check for [**MO0012**](/docs/mocha/v16/diagnostics#mo0012) (open generic) - close the generic type
- Verify the handler implements the correct interface for the messaging pattern you are using
- Ensure the handler is in the same project that references `Mocha.Analyzers`

Expand All @@ -111,7 +111,7 @@ If a class implements more than one messaging interface (e.g., both `IBatchEvent

# Next steps

- [Handlers and Consumers](/docs/mocha/v1/handlers-and-consumers) - handler interfaces, DI scoping, and exception behavior
- [Routing and Endpoints](/docs/mocha/v1/routing-and-endpoints) - how the bus routes messages to registered handlers
- [Sagas](/docs/mocha/v1/sagas) - saga state machines and long-running workflows
- [Mediator](/docs/mocha/v1/mediator) - the mediator uses the same source generation approach for in-process CQRS
- [Handlers and Consumers](/docs/mocha/v16/handlers-and-consumers) - handler interfaces, DI scoping, and exception behavior
- [Routing and Endpoints](/docs/mocha/v16/routing-and-endpoints) - how the bus routes messages to registered handlers
- [Sagas](/docs/mocha/v16/sagas) - saga state machines and long-running workflows
- [Mediator](/docs/mocha/v16/mediator) - the mediator uses the same source generation approach for in-process CQRS
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Choose a handler interface based on the messaging pattern you are implementing:
| `IBatchEventHandler<T>` | Processing multiple events at once for throughput efficiency. |
| `IConsumer<T>` | Accessing raw envelope metadata - headers, correlation IDs, or the full consume context. |

If you have read [Messaging Patterns](/docs/mocha/v1/messaging-patterns), these map directly: `IEventHandler<T>` is for `PublishAsync`, `IEventRequestHandler<TReq>` is for `SendAsync`, and `IEventRequestHandler<TReq, TRes>` is for `RequestAsync`.
If you have read [Messaging Patterns](/docs/mocha/v16/messaging-patterns), these map directly: `IEventHandler<T>` is for `PublishAsync`, `IEventRequestHandler<TReq>` is for `SendAsync`, and `IEventRequestHandler<TReq, TRes>` is for `RequestAsync`.

# Event handler

Expand Down Expand Up @@ -87,7 +87,7 @@ var app = builder.Build();
app.Run();
```

`.AddMyApp()` is a source-generated extension method that discovers all handlers in the assembly and registers them. The source generator found `OrderPlacedHandler`, saw that it implements `IEventHandler<OrderPlaced>`, and emitted a registration call for it. For details on how the source generator works and how to customize the module name, see [Handler Registration](/docs/mocha/v1/handler-registration).
`.AddMyApp()` is a source-generated extension method that discovers all handlers in the assembly and registers them. The source generator found `OrderPlacedHandler`, saw that it implements `IEventHandler<OrderPlaced>`, and emitted a registration call for it. For details on how the source generator works and how to customize the module name, see [Handler Registration](/docs/mocha/v16/handler-registration).

## Verify the handler runs

Expand Down Expand Up @@ -419,7 +419,7 @@ public class OrderAuditConsumer(ILogger<OrderAuditConsumer> logger)
}
```

`IConsumeContext<T>` gives you the deserialized message plus envelope fields: `MessageId`, `CorrelationId`, `ConversationId`, `CausationId`, `SourceAddress`, `DestinationAddress`, `SentAt`, `Headers`, `DeliveryCount`, and more. See [Messages](/docs/mocha/v1/messages) for how correlation identifiers relate to each other.
`IConsumeContext<T>` gives you the deserialized message plus envelope fields: `MessageId`, `CorrelationId`, `ConversationId`, `CausationId`, `SourceAddress`, `DestinationAddress`, `SentAt`, `Headers`, `DeliveryCount`, and more. See [Messages](/docs/mocha/v16/messages) for how correlation identifiers relate to each other.

Register with `.AddConsumer<T>()`:

Expand Down Expand Up @@ -461,11 +461,11 @@ Singleton services are resolved from the root container as usual. If you inject

When `HandleAsync` throws, the behavior depends on the handler type and the middleware pipeline:

- **Event handlers and send handlers:** The exception is caught by the pipeline. By default, Mocha retries the message according to the configured retry policy, then moves it to the dead-letter queue if retries are exhausted. See [Reliability](/docs/mocha/v1/reliability) for retry and fault configuration.
- **Event handlers and send handlers:** The exception is caught by the pipeline. By default, Mocha retries the message according to the configured retry policy, then moves it to the dead-letter queue if retries are exhausted. See [Reliability](/docs/mocha/v16/reliability) for retry and fault configuration.
- **Request handlers:** The exception propagates back to the caller as a fault. If you use `RequestAsync`, it throws on the caller side. The caller receives the error, not a timeout.
- **Batch handlers:** If the handler throws, all messages in the batch fault together. The pipeline treats the entire batch as a failed unit.

When a message arrives, it passes through middleware before reaching your handler. The pipeline handles fault routing, dead-letter delivery, observability, and concurrency limits - without any code in your handler. See [Middleware and Pipelines](/docs/mocha/v1/middleware-and-pipelines) for details on writing custom pipeline middleware.
When a message arrives, it passes through middleware before reaching your handler. The pipeline handles fault routing, dead-letter delivery, observability, and concurrency limits - without any code in your handler. See [Middleware and Pipelines](/docs/mocha/v16/middleware-and-pipelines) for details on writing custom pipeline middleware.

# Publishing from a handler

Expand Down Expand Up @@ -504,17 +504,17 @@ public class OrderPlacedHandler(
}
```

Messages published from within a handler automatically inherit the `ConversationId` and `CorrelationId` from the inbound message. The bus sets `CausationId` on the outgoing message to the `MessageId` of the inbound message. This creates a traceable parent-child chain across services without any extra code. See [Messages](/docs/mocha/v1/messages) for how correlation identifiers work.
Messages published from within a handler automatically inherit the `ConversationId` and `CorrelationId` from the inbound message. The bus sets `CausationId` on the outgoing message to the `MessageId` of the inbound message. This creates a traceable parent-child chain across services without any extra code. See [Messages](/docs/mocha/v16/messages) for how correlation identifiers work.

# Further reading

- [Handler Registration](/docs/mocha/v1/handler-registration) - How the source generator discovers handlers and how to customize registration.
- [Handler Registration](/docs/mocha/v16/handler-registration) - How the source generator discovers handlers and how to customize registration.
- [Event-Driven Consumer](https://www.enterpriseintegrationpatterns.com/patterns/messaging/EventDrivenConsumer.html) - The EIP pattern that defines push-based message consumption, which is what Mocha's handlers implement.
- [Competing Consumers](https://www.enterpriseintegrationpatterns.com/patterns/messaging/CompetingConsumers.html) - When multiple instances of your service run, they compete for messages on the same queue. This is the concurrency model for Mocha handlers under load.

# Next steps

Your handlers are registered. Learn how the source generator discovers and registers them in [Handler Registration](/docs/mocha/v1/handler-registration), or how Mocha routes messages to them in [Routing and Endpoints](/docs/mocha/v1/routing-and-endpoints).
Your handlers are registered. Learn how the source generator discovers and registers them in [Handler Registration](/docs/mocha/v16/handler-registration), or how Mocha routes messages to them in [Routing and Endpoints](/docs/mocha/v16/routing-and-endpoints).

> **Runnable examples:** [BatchHandler](https://github.com/ChilliCream/graphql-platform/tree/main/src/Mocha/src/Examples/HandlersAndConsumers/BatchHandler), [LowLevelConsumer](https://github.com/ChilliCream/graphql-platform/tree/main/src/Mocha/src/Examples/HandlersAndConsumers/LowLevelConsumer), [CustomConsumer](https://github.com/ChilliCream/graphql-platform/tree/main/src/Mocha/src/Examples/HandlersAndConsumers/CustomConsumer)
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,6 @@ The response is a JSON document describing the full bus topology: the host, regi

# Next steps

- [Observability](/docs/mocha/v1/observability) - Add OpenTelemetry tracing and metrics to the bus.
- [Reliability](/docs/mocha/v1/reliability) - Configure outbox, inbox, and circuit breakers.
- [Transports](/docs/mocha/v1/transports) - Configure RabbitMQ, InMemory, and multi-transport setups.
- [Observability](/docs/mocha/v16/observability) - Add OpenTelemetry tracing and metrics to the bus.
- [Reliability](/docs/mocha/v16/reliability) - Configure outbox, inbox, and circuit breakers.
- [Transports](/docs/mocha/v16/transports) - Configure RabbitMQ, InMemory, and multi-transport setups.
Loading