Skip to main content
Bir domain event, aggregate içinde olup bitmiş anlamlı bir gerçeği anlatır: “Kullanıcı oluşturuldu”, “OTP üretildi”, “Bağış başvurusu onaylandı”. Geçmiş zamanlı isimlendirilir; çünkü olay zaten gerçekleşmiştir, iptal edilemez. Domain event’ler yan etkileri ana iş akışından ayırır: aggregate yalnızca kendi durumunu değiştirir ve bir olay yayar; SMS gönderme, cache temizleme, başka servise haber verme gibi işler ayrı handler’lara düşer.

DomainEvent + INotification

Her event DomainEvent tabanından türer (Version 7 GUID kimliği + UTC zaman damgası alır) ve MediatR’ın INotification arayüzünü uygular:
Event payload’u değişmezdir (yalnız get property’ler). Tüketici verisini değiştiremez; sadece okur. Olay, gerçekleşmiş bir durumun fotoğrafıdır.

AddDomainEvent ile aggregate’ta yayma

Aggregate, durumunu değiştirdiği davranış metodunun sonunda olayı kuyruğa ekler. Olay hemen işlenmez — yalnızca kayıt persist edildikten sonra dispatch edilmek üzere biriktirilir.
AddDomainEvent EntityBase üzerinde tanımlıdır ve olayı entity’nin iç DomainEvents listesine ekler.

Dispatch: SaveEntitiesAsync sonrası MediatR

Olaylar, yazma işlemi başarıyla tamamlandıktan sonra yayınlanır. Akış IUnitOfWork.SaveEntitiesAsync içinde gerçekleşir: SaveChanges çağrısından sonra change tracker’daki tüm entity’lerin DomainEvents listesi toplanır, MediatR Publish ile yayınlanır ve ardından ClearDomainEvents() ile temizlenir.
Sıralama önemlidir: olaylar veritabanı yazımından sonra dispatch edilir. Böylece bir handler patlarsa bile durum zaten tutarlı şekilde persist edilmiştir; ayrıca handler’lar oluşturulan kaydın gerçekten var olduğuna güvenebilir. Detaylar Veri Katmanı’ndadır.

Gerçek event listesi

DiyanetCleanArchitecture.Domain/Events/ klasöründeki olaylardan bir kesit:
UserCreatedDomainEvent, UserOtpGeneratedDomainEvent, UserOtpResentDomainEvent, UserPhoneNumberVerifiedDomainEvent, UserEmailVerifiedDomainEvent, UserRoleAssignedDomainEvent, UserRoleRevokedDomainEvent, UserTokensInvalidatedDomainEvent, UserTotpEnabledDomainEvent.
CitizenCreatedDomainEvent, CitizenOtpGeneratedDomainEvent, CitizenOtpResentDomainEvent, CitizenPhoneNumberVerifiedDomainEvent, CitizenEmailVerifiedDomainEvent, CitizenAccountDeactivatedDomainEvent, CitizenTokensInvalidatedDomainEvent, CitizenRefreshTokenRevokedDomainEvent.
FaqCreatedDomainEvent, FaqUpdatedDomainEvent, FaqDeletedDomainEvent, FaqReorderedDomainEvent.
BagisBasvuruOlusturulduDomainEvent, BagisBasvuruIncelemeyeAlindiDomainEvent, BagisBasvuruBelgeBeklendiDomainEvent, BagisBasvuruOnaylandiDomainEvent, BagisBasvuruReddedildiDomainEvent, BagisBasvuruIptalEdildiDomainEvent, BagisBasvuruOdemesiTamamlandiDomainEvent.
EtkinlikBasvuruOlusturulduDomainEvent, EtkinlikBasvuruOnaylandiDomainEvent, EtkinlikBasvuruPlanKontenjanDolduDomainEvent, … ; SupportTicketCreatedDomainEvent, SupportTicketAssignedDomainEvent, SupportTicketStatusChangedDomainEvent, SupportTicketCommentAddedDomainEvent.
İsimlendirme tutarlıdır: domain dilinde Türkçe kavramlar (Bağış, Etkinlik başvurusu) Türkçe event isimleri taşır — ...OlusturulduDomainEvent, ...OnaylandiDomainEvent, ...ReddedildiDomainEvent. Teknik/altyapı olayları (User, Faq) İngilizce kalır.

Handler örnekleri

Bir domain event’i birden fazla handler dinleyebilir; her biri tek bir yan etkiden sorumludur.

SMS / E-posta gönderimi

Aynı olayın e-posta tarafını SendOtpEmailDomainEventHandler üstlenir (type == OtpType.Email ise).

Cache invalidation

Domain event → integration event köprüsü

Bazı handler’lar olayı integration event’e çevirip mesaj kuyruğuna basar (sistemler arası iletişim):

Domain event vs integration event

Domain event’ler asla doğrudan kuyruğa yayınlanmaz; süreç içi kalır ve domain tiplerini (VO) taşıyabilir. Sistem dışına bir şey duyurmak gerektiğinde, bir handler içinde ayrı bir integration event üretip IEventBus ile yayınlayın. Bu ayrım, domain’i mesajlaşma altyapısından bağımsız tutar.

Sonraki adımlar

Aggregate'ler

AddDomainEvent’in davranış metotlarında kullanımı.

Event-Driven Akış

Dispatch, MassTransit Outbox ve RabbitMQ tüketici zinciri.

Veri Katmanı

SaveEntitiesAsync ve DispatchDomainEventsAsync detayları.

Yeni domain event ekleme

Adım adım playbook.