Domain Events pattern, event-driven architecture ve asynchronous processing. Event sourcing ve CQRS pattern implementasyonları.
DDD
Events
Domain
Architecture
Async
Repository ve Unit of Work ile birlikte veri tutarlılığını ve işlem bütünlüğünü nasıl yöneteceğimizi öğrendik.
Ancak gerçek dünyada uygulamalar yalnızca veri kaydetmekle kalmaz — aynı zamanda bir olay meydana geldiğinde, bu olayı başka katmanlara veya sistemlere de iletmemiz gerekir
İşte bu tür ihtiyaçlar için Domain-Driven Design içinde çok önemli bir rolü olan kavram devreye girer: Event (Olay).
📣 Event Nedir?
Event, sistem içinde bir şeyin olduğunu haber veren domain kavramıdır.
Başka bir deyişle:
"Şu olay oldu, haberiniz olsun!" diyen bir mesajdır.
DDD’de Event’ler, domain'deki önemli durum değişikliklerini veya işlemleri temsil eder.
Örneğin:
Sipariş oluşturuldu
Kullanıcı kaydoldu
Ürün stoğu tükendi
Bunların her biri, domain içinde bir olaydır ve başka nesnelerin/servislerin bunlara tepki vermesini gerektirebilir.
🎯 Event Neden Vardır?
Amaç
Açıklama
Gevşek bağlılık
Kodun farklı parçalarını birbirine sıkı sıkıya bağlamadan haberleşmelerini sağlar
Yan etkileri ayırmak
Bir işlem olduysa, bu işleme bağlı başka işlemleri (e-posta gönderme, loglama vb.) domain mantığından ayırmak mümkün olur
Domain diliyle iletişim kurmak
Olaylar, domain dilinde tanımlanır: OrderCreatedEvent, StockDecreasedEvent gibi
🔁 Event Türleri
1. Domain Event
Domain içinde tanımlanır
Entity veya Aggregate Root tarafından fırlatılır
Domain mantığına aittir
2. Integration Event
Sistemler arası iletişim sağlar (örneğin RabbitMQ, Kafka, SignalR)
Genellikle Application veya Infrastructure katmanında kullanılır
Microservice mimarisinde sık kullanılır
Şu an biz öncelikle Domain Event’e odaklanacağız.
Şimdi çalışmalarımıza başlamadan önce Agregate olarak daha önce tanımladığımız Order Domain'i dikkate alalım.
bash
using DomainDrivenDesign.Domain.Abstractions;using DomainDrivenDesign.Domain.Shared.DomainDrivenDesign.Domain.Shared;namespace DomainDrivenDesign.Domain.Orders;public sealed class Order : Entity
{ public Order(Guid id, string orderNumber, DateTime createdDate, OrderStatusEnum status): base(id){ OrderNumber = orderNumber; CreatedDate = createdDate; Status = status; OrderLines = new List<OrderLine>();} public string OrderNumber { get; private set;} public DateTime CreatedDate { get; private set;} public OrderStatusEnum Status { get; private set;} public ICollection<OrderLine> OrderLines { get; private set;} public void CreateOrderLine(List<CreateOrderDto> createOrderDtos){ foreach (var item in createOrderDtos){if(item.Quantity <1){ throw new ArgumentException("Sipariş adedi 1 den az olamaz!");} //kalan iş kuralları
OrderLine orderLine = new( Guid.NewGuid(),
Id,
item.ProductId,
item.Quantity,
new(item.Amount, Currency.FromCode(item.Currency))); OrderLines.Add(orderLine); orderLine.AddProduct(item.product); // Product nesnesini OrderLine'a ekliyoruz
}} public void RemoveOrderLine(Guid orderLineId){ var orderLine = OrderLines.FirstOrDefault(p => p.Id == orderLineId);if(orderLine is null){ throw new ArgumentException("Silmek istediğiniz sipariş kalemi bulunamadı!");} OrderLines.Remove(orderLine);}}
Süper! Şimdi verdiğin Order Aggregate Root üzerinden adım adım bir senaryo üzerinden Domain Event sistematiği kuracağız.
Şu sorulara net cevaplar vereceğiz:
✔️ Neden event tanımlarız?
✔️ Nasıl tanımlarız?
✔️ Nerede ve nasıl fırlatılır?
✔️ Kim tarafından işlenir?
🎯 Senaryo: Sipariş Oluşturma Süreci
🧾 İş Akışı:
Kullanıcı bir sipariş verir.
Siparişteki her ürün için stok miktarı kontrol edilir.
Eğer ürün stokta yoksa veya yetersizse, bu durum bir çalışana bildirilir.