Skip to main content
Integration event altyapısı üç pakete bölünür:
  • BuildingBlocks.Contracts.EventsIntegrationEvent base sınıfı ve IIntegrationEventHandler<T> kontratları (servisler arası paylaşılır).
  • BuildingBlocks.EventBusIEventBus soyutlaması, subscription registry, builder pattern.
  • BuildingBlocks.EventBus.MassTransit.RabbitMqaktif implementasyon: MassTransit + RabbitMQ, EF Outbox, retry/redelivery/DLX.
BuildingBlocks.EventBus.EventBusRabbitMQ (ham RabbitMQ.Client tabanlı) legacy’dir; yeni geliştirmede kullanılmaz. Outbox ve delayed redelivery yalnızca MassTransit paketinde vardır.
Uçtan uca event akışı (domain event → integration event → Outbox → consumer) için Event-Driven Akış grubuna bakın.

Kontratlar

TipDetayAmaç
IntegrationEventGuid Id (v7), DateTime CreatedAt (UTC); [JsonConstructor] deserialize’da Id/timestamp’i korurTü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)
IIntegrationEventHandlerTask Handle(IntegrationEvent @event)Tipsiz base — keyed DI için
CacheInvalidationIntegrationEventIReadOnlyCollection<string> Tags, string SourceNodeIdMulti-instance L1 cache senkron event’i (echo guard SourceNodeId)

IEventBus

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.
ÜyeVarsayılanAçıklama
Host / VirtualHost / Username / Passwordlocalhost / / / guest / guestBağlantı bilgileri
ExchangeNameintegration_event_busTüm servislerin paylaştığı topic exchange
ExchangeTypetopicExchange tipi
RoutingKeyPrefixintegration.eventRouting key öneki — {prefix}.{EventName}
RetryCount3In-process retry sayısı
RetryIntervalSeconds2In-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.
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;
}
// 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>();
{
  "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

// 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

Integration event'ler

Event tasarımı, idempotency ve versiyonlama.

Outbox pattern

EF Outbox ile atomik publish.

RabbitMQ topolojisi

Exchange, kuyruk ve routing key konvansiyonları.

Cache invalidation

CacheInvalidationIntegrationEvent ile multi-instance senkron.