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
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/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:
İ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.Idile işlenmişlik kontrolü, upsert semantiği, veya doğal idempotent işlem (örn.RemoveByTagLocallyAsynctekrar ç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.