> ## Documentation Index
> Fetch the complete documentation index at: https://docs.diyanet.pro/llms.txt
> Use this file to discover all available pages before exploring further.

# BuildingBlocks.EventBus

> MassTransit + RabbitMQ integration event dağıtımı — EF Outbox, retry, delayed redelivery.

Integration event altyapısı üç pakete bölünür:

* **`BuildingBlocks.Contracts.Events`** — `IntegrationEvent` base sınıfı ve `IIntegrationEventHandler<T>` kontratları (servisler arası paylaşılır).
* **`BuildingBlocks.EventBus`** — `IEventBus` soyutlaması, subscription registry, builder pattern.
* **`BuildingBlocks.EventBus.MassTransit.RabbitMq`** — **aktif** implementasyon: MassTransit + RabbitMQ, EF Outbox, retry/redelivery/DLX.

<Note>
  `BuildingBlocks.EventBus.EventBusRabbitMQ` (ham `RabbitMQ.Client` tabanlı) **legacy**'dir; yeni geliştirmede kullanılmaz. Outbox ve delayed redelivery yalnızca MassTransit paketinde vardır.
</Note>

<Info>Uçtan uca event akışı (domain event → integration event → Outbox → consumer) için [Event-Driven Akış](/events/overview) grubuna bakın.</Info>

## Kontratlar

| Tip                                 | Detay                                                                                               | Amaç                                                                      |
| ----------------------------------- | --------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------- |
| `IntegrationEvent`                  | `Guid Id` (v7), `DateTime CreatedAt` (UTC); `[JsonConstructor]` deserialize'da Id/timestamp'i korur | Tüm integration event POCO'larının base'i; `INotification` implement eder |
| `IIntegrationEventHandler<T>`       | `Task Handle(T @event)`                                                                             | Tipli handler kontratı (tüketici servis implement eder)                   |
| `IIntegrationEventHandler`          | `Task Handle(IntegrationEvent @event)`                                                              | Tipsiz base — keyed DI için                                               |
| `CacheInvalidationIntegrationEvent` | `IReadOnlyCollection<string> Tags`, `string SourceNodeId`                                           | Multi-instance L1 cache senkron event'i (echo guard `SourceNodeId`)       |

## `IEventBus`

```csharp theme={null}
public interface IEventBus
{
    Task PublishAsync(IntegrationEvent @event, CancellationToken cancellationToken = default);
}
```

Implementasyon `MassTransitEventBus`'tır; DI döngüsünü önlemek için `IPublishEndpoint`'i lazy resolve eder ve event tipine göre routing key belirler.

## `MassTransitRabbitMqOptions`

`MassTransitRabbitMq` bölümüne bind edilir.

| Üye                                              | Varsayılan                            | Açıklama                                                 |
| ------------------------------------------------ | ------------------------------------- | -------------------------------------------------------- |
| `Host` / `VirtualHost` / `Username` / `Password` | `localhost` / `/` / `guest` / `guest` | Bağlantı bilgileri                                       |
| `ExchangeName`                                   | `integration_event_bus`               | Tüm servislerin paylaştığı topic exchange                |
| `ExchangeType`                                   | `topic`                               | Exchange tipi                                            |
| `RoutingKeyPrefix`                               | `integration.event`                   | Routing key öneki — `{prefix}.{EventName}`               |
| `RetryCount`                                     | `3`                                   | In-process retry sayısı                                  |
| `RetryIntervalSeconds`                           | `2`                                   | In-process retry'lar arası bekleme                       |
| `RedeliveryIntervalsMinutes`                     | `[0.16, 1, 5]`                        | Delayed redelivery aşamaları (dakika): 10 sn, 1 dk, 5 dk |

`EventBusOptions` (`EventBus` bölümü): `SubscriptionClientName` (kuyruk adı, örn. `DiyanetCleanArchitecture`), `ConcurrentMessageLimit` (varsayılan 10).

## DI kaydı

`AddMassTransitRabbitMqEventBus(...)` bus'ı kurar; `AddMassTransitSubscription<T, TH>()` her event–handler çiftini fluent kaydeder.

```csharp theme={null}
public static IEventBusBuilder AddMassTransitSubscription<T, TH>(this IEventBusBuilder builder)
    where T : IntegrationEvent
    where TH : class, IIntegrationEventHandler<T>
{
    // BuildingBlocks.EventBus registry'sine ekler (KeyedService + EventTypes)
    EventBusBuilderExtensions.AddSubscription<T, TH>(builder);
    // MassTransit consumer'ını scope'a kaydeder
    builder.Services.AddScoped<IntegrationEventConsumer<T>>();
    return builder;
}
```

```csharp theme={null}
// Program.cs
builder.Services
    .AddMassTransitRabbitMqEventBus(builder.Configuration, x =>
    {
        // EF Outbox — MassTransit.EntityFrameworkCore
        // messaging.outbox_message / outbox_state / inbox_state tabloları
    })
    .AddMassTransitSubscription<UserCreatedIntegrationEvent, SendWelcomeEmailHandler>()
    .AddMassTransitSubscription<UserCreatedIntegrationEvent, NotifyAdminHandler>();
```

```json theme={null}
{
  "EventBus": {
    "SubscriptionClientName": "DiyanetCleanArchitecture",
    "ConcurrentMessageLimit": 10
  },
  "MassTransitRabbitMq": {
    "Host": "rabbitmq",
    "VirtualHost": "/",
    "Username": "guest",
    "Password": "guest",
    "ExchangeName": "integration_event_bus",
    "ExchangeType": "topic",
    "RoutingKeyPrefix": "integration.event",
    "RetryCount": 3,
    "RetryIntervalSeconds": 2,
    "RedeliveryIntervalsMinutes": [0.16, 1, 5]
  }
}
```

## Kullanım — publish + handle

```csharp theme={null}
// Event tanımı (Contracts.Events'te)
public class UserCreatedIntegrationEvent : IntegrationEvent
{
    public Guid UserId { get; set; }
    public string Email { get; set; } = default!;

    public UserCreatedIntegrationEvent() { }
    public UserCreatedIntegrationEvent(Guid userId, string email)
        => (UserId, Email) = (userId, email);
}

// Yayınlama — domain event handler'dan (UserCreatedDomainEventHandler)
public class UserCreatedDomainEventHandler(IEventBus bus)
    : INotificationHandler<UserCreatedDomainEvent>
{
    public Task Handle(UserCreatedDomainEvent e, CancellationToken ct)
        => bus.PublishAsync(new UserCreatedIntegrationEvent(e.UserId, e.Email), ct);
}

// Tüketme — idempotent
public class SendWelcomeEmailHandler(IEmailService email)
    : IIntegrationEventHandler<UserCreatedIntegrationEvent>
{
    public async Task Handle(UserCreatedIntegrationEvent @event)
    {
        if (string.IsNullOrEmpty(@event.Email)) return;
        await email.SendWelcomeAsync(@event.Email);
    }
}
```

## Retry / DLX stratejisi

İki katmanlı, ikisi de sınırlı:

1. **In-process retry** (`UseMessageRetry`) — `RetryCount` × `RetryIntervalSeconds` (örn. 3 × 2 sn). Mesaj kuyruktan ayrılmaz.
2. **Delayed redelivery** (`UseDelayedRedelivery`) — in-process tükenince mesaj `RedeliveryIntervalsMinutes` aşamalarıyla (10 sn → 1 dk → 5 dk) gecikmeli olarak kuyruğa geri konur. RabbitMQ `rabbitmq_delayed_message_exchange` plugin'i gerekir.

Toplam deneme sayısı `(RetryCount + 1) × (RedeliveryIntervalsMinutes.Length + 1)` ile sınırlıdır. Tüm denemeler tükenince mesaj kalıcı olarak `{queue}_error` (DLX) kuyruğuna düşer.

## İlgili

<CardGroup cols={2}>
  <Card title="Integration event'ler" icon="paper-plane" href="/events/integration-events">
    Event tasarımı, idempotency ve versiyonlama.
  </Card>

  <Card title="Outbox pattern" icon="box-archive" href="/events/outbox-pattern">
    EF Outbox ile atomik publish.
  </Card>

  <Card title="RabbitMQ topolojisi" icon="diagram-project" href="/events/rabbitmq-topology">
    Exchange, kuyruk ve routing key konvansiyonları.
  </Card>

  <Card title="Cache invalidation" icon="eraser" href="/caching/multi-instance">
    CacheInvalidationIntegrationEvent ile multi-instance senkron.
  </Card>
</CardGroup>
