Skip to main content

IntegrationEvent base

Cross-service event’lerin temel sınıfı (src/BuildingBlocks/.../Contracts.Events/IntegrationEvent.cs). Tüm event POCO’ları bundan türer; INotification’dır:
[JsonConstructor] + [JsonInclude] private init’e izin verir: receiver tarafında deserialize edilirken Id ve CreatedAt orijinal değerlerini korur (yeniden üretilmez). Bu, idempotency ve duplicate detection için önemlidir.

IBusEvent ve IBusMessage

MediatorExtension bir domain event’i in-process mı yoksa bus’a mı göndereceğine IBusEvent marker’ı ile karar verir:
MassTransitEventBus.PublishAsync routing key’i şöyle belirler: event IBusEvent ise GetEventKey(), değilse tip adı. RoutingKeyPrefix (default integration.event) ile birleştirilir:

Örnek: UserCreatedIntegrationEvent

[MessageUrn("urn:event:...:v1")] cross-service deserialization için stabil bir identity sağlar — tip adı/namespace değişse bile mesajlar eşleşir. Versiyon son ek (:v1) şema evrimi içindir.
CacheInvalidationIntegrationEvent de aynı kalıbı kullanır (urn:event:cache-invalidation:v1); ayrıntı: Multi-Instance Senkron.

Handler kontratı: IIntegrationEventHandler<T>

Üretici servis event’i Contracts.Events’ten import eder; tüketici servis handler’ı implement eder:

Kayıt: AddMassTransitSubscription<T, TH>

Event/handler çiftini iki işle birden register eder (BuildingBlocks.EventBus.MassTransit.RabbitMq/EventBusBuilderExtensions.cs):
Application katmanındaki kullanım (Application/DependencyInjection.cs):
UserCreatedIntegrationEvent ve CitizenCreatedIntegrationEvent şu an yayın-only: yayınlanır ve outbox/RabbitMQ’ya gider, ama bu projede dinleyen consumer henüz yoktur. Cross-service tüketici çıktığında AddMassTransitSubscription ile kayıt eklenir.

IntegrationEventConsumer<T> — keyed handler çözümü

Tek bir generic consumer tüm tipler için çalışır; gelen mesaj tipine kayıtlı tüm handler’ları keyed DI’dan resolve eder ve sırayla çağırır:
Aynı event’e birden çok handler kaydedilebilir (keyed services), ama RabbitMQ tarafında consumer tipi tektir — binding’ler distinct event tipleri üzerinden kurulur.

İdempotent handler

Mesaj en az bir kez (at-least-once) teslim edilebilir: retry, redelivery veya broker yeniden teslimi sonucu aynı event iki kez gelebilir. Bu yüzden handler’lar idempotent yazılmalı:
  • Outbox DuplicateDetectionWindow (30 dk) MassTransit Inbox tarafında tekrarları yakalar (bkz. Outbox Pattern).
  • Yine de handler kendi tarafında güvende olmalı: event.Id ile işlenmişlik kontrolü, upsert semantiği, veya doğal idempotent işlem (örn. RemoveByTagLocallyAsync tekrar çağrılması zararsızdır).

İlgili

Outbox Pattern

Transactional outbox + Inbox duplicate detection.

RabbitMQ Topology

Exchange, routing key, queue, retry.

Domain Events

Domain event’ten integration event yayma.

Multi-Instance Senkron

CacheInvalidationIntegrationEvent örneği.