# Overview

Hermodr ships ready-made channel implementations for the most common messaging transports, plus reliability-oriented publisher extensions such as the transactional outbox and dead-letter replay. You install only what you need and register the pieces in the `EventPublisherBuilder` chain.

## Available channels and reliability extensions

| Feature                                                               | Package                             | Best for                                                                                          |
| --------------------------------------------------------------------- | ----------------------------------- | ------------------------------------------------------------------------------------------------- |
| [Azure Service Bus](/publisher-channels/azure-service-bus.md)         | `Hermodr.Publisher.AzureServiceBus` | Cloud-native apps on Azure, reliable queue- or topic-based delivery                               |
| [RabbitMQ](/publisher-channels/rabbitmq.md)                           | `Hermodr.Publisher.RabbitMq`        | On-premise or self-hosted AMQP broker, fine-grained routing                                       |
| [MassTransit](/publisher-channels/masstransit.md)                     | `Hermodr.Publisher.MassTransit`     | Projects already using MassTransit; broker-agnostic                                               |
| [Webhook](/publisher-channels/webhook.md)                             | `Hermodr.Publisher.Webhook`         | Delivering events to external HTTP endpoints with HMAC signing                                    |
| [Publish Error Handling](/publisher-channels/error-handling.md)       | `Hermodr.Publisher`                 | Cross-cutting interception of publish failures for logging, policy, auditing, and custom recovery |
| [Transactional Outbox](/publisher-channels/outbox.md)                 | `Hermodr.Publisher.Outbox`          | Guaranteed at-least-once delivery via a transactional outbox table                                |
| [Dead-Letter Handling and Replay](/publisher-channels/dead-letter.md) | `Hermodr.Publisher.DeadLetter`      | Capturing failed channel deliveries, persisting them, and replaying them later                    |
| [Test (in-memory)](/testing/testing.md)                               | `Hermodr.TestPublisher`             | Unit and integration tests                                                                        |

## Multiple channels

You can register more than one channel at a time. The publisher will fan every event out to **all** registered channels:

```csharp
builder.Services
    .AddEventPublisher(options => options.Source = new Uri("https://myapp.example.com"))
    .AddServiceBus(options =>
    {
        options.ConnectionString = "...";
        options.QueueName = "events";
    })
    .AddWebhooks(options =>
    {
        options.EndpointUrl  = "https://partner.example.com/events";
        options.SigningSecret = "s3cr3t";
    });
```

## Named channels

When two or more channels of the same transport type are registered simultaneously, assign each a **logical name** via the `ChannelName` property on its options. At publish time, target the right channel by name using the convenience extension methods or by setting `ChannelName` on the per-call options:

```csharp
builder.Services
    .AddEventPublisher()
    .AddRabbitMq(opts => { opts.ChannelName = "rabbit-orders"; opts.ExchangeName = "orders"; })
    .AddRabbitMq(opts => { opts.ChannelName = "rabbit-notifications"; opts.ExchangeName = "notifications"; });

// Publish only to the "rabbit-orders" channel
await publisher.PublishAsync(orderPlaced, channelName: "rabbit-orders");
```

See [Named Channels](/publisher-channels/named-channels.md) for the full guide.

## Typed channels

Every built-in channel supports a **typed** registration variant (`AddRabbitMq<TEvent>()`, `AddServiceBus<TEvent>()`, `AddMassTransit<TEvent>()`, `AddWebhooks<TEvent>()`) that routes **only** events of the specified data class to that channel. Typed channels also support a two-level options hierarchy — a base set of defaults merged with per-event-type overrides — so you can share common settings and specialise only what differs.

```csharp
builder.Services
    .AddEventPublisher()
    .AddRabbitMq(opts => { opts.ConnectionString = "amqp://..."; opts.ExchangeName = "events"; })
    .AddRabbitMq<OrderPlacedData>(opts => { opts.ExchangeName = "orders"; opts.QueueName = "order-placed"; });
```

See [Typed Channels](/publisher-channels/typed-channels.md) for the full guide.

## Implementing a custom channel

See [Publish Channels](/core-concepts/publish-channels.md#implementing-a-custom-channel) for instructions on creating and registering your own `IEventPublishChannel` or `IEventPublishChannel<TEvent>`.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://hermodr.deveel.org/publisher-channels/publishers.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
