Takip et

C# Mimarisinde Ustalık: .NET’te Olay Tabanlı Mimari (Mesajlaşma ile Temiz Sınırlar) – Bölüm 12

Modern yazılım sistemleri, giderek artan karmaşıklık, ölçeklenebilirlik ve esneklik gereksinimleriyle karşı karşıyadır. Bu bağlamda, geleneksel …

C# Mimarisinde Ustalık: .NET’te Olay Tabanlı Mimari (Mesajlaşma ile Temiz Sınırlar) – Bölüm 12

Modern yazılım sistemleri, giderek artan karmaşıklık, ölçeklenebilirlik ve esneklik gereksinimleriyle karşı karşıyadır. Bu bağlamda, geleneksel monolitik mimariler yerini daha modüler, dağıtık ve reaktif yapılara bırakmaktadır. Olay Tabanlı Mimari (Event-Driven Architecture – EDA), .NET ekosisteminde de popülaritesi artan, sistemler arası iletişimi olaylar aracılığıyla sağlayan güçlü bir yaklaşımdır. Bu makalenin on ikinci bölümünde, EDA’nın temel prensiplerini, mesajlaşma mekanizmalarıyla temiz sınırlar oluşturmanın önemini ve C#/.NET ortamında bu mimariyi nasıl uygulayabileceğimizi derinlemesine inceleyeceğiz. Amacımız, gevşek bağlı, ölçeklenebilir ve sürdürülebilir uygulamalar geliştirmek için olay tabanlı mimarinin gücünden nasıl yararlanabileceğimizi göstermektir.

Olay Tabanlı Mimariye Giriş ve Temel Kavramlar

Olay Tabanlı Mimari (EDA), sistem bileşenlerinin birbirleriyle doğrudan çağrılar yerine olaylar aracılığıyla iletişim kurduğu bir yazılım tasarım paradigmaları bütünüdür. Bir bileşen bir olay meydana geldiğinde bunu yayımlar ve diğer bileşenler bu olaylara abone olarak tepki verir. Bu yaklaşım, özellikle dağıtık sistemlerde ve mikroservis mimarilerinde büyük avantajlar sunar.

Olay Tabanlı Mimari Nedir?

EDA’da, bir sistemdeki her türlü değişiklik veya önemli durum geçişi bir “olay” olarak kabul edilir. Örneğin, bir kullanıcının kaydolması, bir siparişin oluşturulması veya bir ürünün stok durumunun değişmesi birer olaydır. Bu olaylar, olayı üreten “olay üreticisi” (event producer) tarafından yayımlanır ve bu olaylarla ilgilenen “olay tüketicileri” (event consumers) tarafından dinlenir ve işlenir. Bu model, bileşenler arasında doğrudan bağımlılıkları ortadan kaldırarak daha esnek ve adapte edilebilir sistemler oluşturulmasına olanak tanır.

Geleneksel Mimarilere Göre Avantajları

Geleneksel katmanlı veya monolitik mimarilerde, bileşenler genellikle birbirlerini doğrudan çağırır ve bu da yüksek bağımlılığa yol açar. EDA ise bu bağımlılığı gevşetir. Temel avantajları şunlardır:

  • Gevşek Bağlılık (Loose Coupling): Üreticiler tüketicileri bilmez, sadece olayları yayımlar. Tüketiciler de üreticileri bilmez, sadece olaylara abone olur. Bu, her bileşenin bağımsız olarak geliştirilmesine, dağıtılmasına ve ölçeklenmesine olanak tanır.
  • Ölçeklenebilirlik: Olay tüketicileri paralel olarak çalışabilir, bu da iş yükünün kolayca dağıtılmasını sağlar.
  • Esneklik ve Genişletilebilirlik: Yeni bir özellik eklemek genellikle yeni bir olay tüketicisi yazmak kadar basittir, mevcut kodu değiştirmeye gerek kalmaz.
  • Hata Toleransı: Bir bileşen arızalansa bile, diğer bileşenler olayları işlemeye devam edebilir veya olay kuyruklarında bekleyebilir.

Temel Bileşenler: Olaylar, Üreticiler, Tüketiciler

EDA’nın üç ana bileşeni vardır:

  • Olay (Event): Sistemde meydana gelen önemli bir durumu veya değişikliği temsil eden, geçmişe dönük bir gerçektir. Genellikle sadece veri içerir ve bir komut gibi bir eylem bekletmez. Örnek: SiparişOluşturuldu, KullanıcıKaydoldu.
  • Olay Üreticisi (Event Producer / Publisher): Bir olayın meydana geldiğini algılayan ve bu olayı yayımlayan bileşendir. Bir olayı yayımladığında, bu olayı kimin tüketeceğini veya nasıl işleneceğini bilmez.
  • Olay Tüketicisi (Event Consumer / Subscriber): Belirli olay türlerine abone olan ve bu olaylar yayımlandığında belirli iş mantığını yürüten bileşendir.

Temiz Sınırlar ve Mesajlaşmanın Önemi

Olay tabanlı mimaride “temiz sınırlar” kavramı, sistemin farklı modüllerinin veya mikroservislerinin birbirlerinden bağımsız, kendi sorumluluk alanları içerisinde kalmasını ifade eder. Mesajlaşma, bu sınırları korumanın ve sistemler arası iletişimi sağlıklı bir şekilde sağlamanın anahtarıdır.

Gevşek Bağlılık (Loose Coupling)

Gevşek bağlılık, bir bileşenin diğer bileşenler hakkında mümkün olduğunca az bilgiye sahip olması anlamına gelir. EDA’da bu, olay üreticisinin tüketicileri, tüketicilerin de üreticileri bilmemesiyle sağlanır. Üretici sadece bir olayı yayımlar; bu olayı kimin, ne zaman veya nasıl işleyeceğini umursamaz. Bu sayede, bir bileşende yapılan değişiklikler diğer bileşenleri doğrudan etkilemez, sistemin genel esnekliğini ve sürdürülebilirliğini artırır.

Sınırların Tanımlanması: Bounded Contexts

Domain-Driven Design (DDD) prensiplerinden biri olan “Bounded Context” (Sınırlı Bağlam), karmaşık bir iş alanını daha küçük, yönetilebilir ve tutarlı bağlamlara ayırmayı ifade eder. Her bağlamın kendi içinde tutarlı bir dili, modeli ve sorumlulukları vardır. Olay tabanlı mimaride, her Bounded Context genellikle kendi olaylarını yayımlar ve diğer bağlamların olaylarını tüketir. Bu, her bağlamın kendi iç işleyişini dış dünyadan soyutlamasına ve böylece temiz sınırlar oluşturmasına yardımcı olur.

Örneğin, bir e-ticaret uygulamasında “Sipariş Yönetimi” ve “Stok Yönetimi” ayrı Bounded Context’ler olabilir. Sipariş Yönetimi bir sipariş oluşturduğunda SiparişOluşturuldu olayını yayımlar. Stok Yönetimi bu olayı dinler ve ilgili ürünün stoğunu günceller. Bu sayede iki bağlam birbirine sıkıca bağlanmaz.

Mesajlaşmanın Rolü: Senkronizasyon ve İletişim

Mesajlaşma, olay tabanlı mimarinin kalbinde yer alır. Olayların güvenilir bir şekilde üreticiden tüketiciye iletilmesini sağlar. Mesajlaşma sistemleri (mesaj kuyrukları veya olay veriyolları), olayları tamponlar, dağıtır ve genellikle “at least once” (en az bir kez) veya “exactly once” (tam olarak bir kez) teslim garantisi sunar. Bu, sistemler arası iletişimin asenkron ve güvenilir olmasını sağlar. Ayrıca, mesajlaşma sayesinde farklı teknolojilerle yazılmış sistemler bile olaylar aracılığıyla iletişim kurabilir, bu da entegrasyonu kolaylaştırır.

Domain Olayları ve Entegrasyon Olayları

Olay tabanlı mimaride iki ana olay türü bulunur: Domain Olayları ve Entegrasyon Olayları. Bu iki tür arasındaki farkı anlamak, mimarinizi doğru bir şekilde tasarlamanız için kritik öneme sahiptir.

Domain Olayları (Domain Events) Nedir?

Domain Olayları, belirli bir Bounded Context (Sınırlı Bağlam) içinde meydana gelen ve o bağlamın iş mantığı için önemli olan olaylardır. Genellikle aynı mikroservis veya modül içindeki farklı bileşenler arasında iletişim kurmak için kullanılırlar. Bir domain olayı, bir iş işleminin sonucunu temsil eder ve genellikle bir işlem (transaction) kapsamında yayımlanır. Örneğin, bir SiparişOluşturuldu olayı, Sipariş domain’i içinde meydana gelir ve aynı servis içindeki Stok domain’ini veya Bildirim domain’ini tetikleyebilir.

Domain olayları, sistemin içindeki bileşenleri birbirine gevşek bir şekilde bağlar ve aynı bağlam içinde yan etkilerin (side effects) yönetilmesine yardımcı olur. Genellikle senkron veya in-process bir olay veriyolu (event bus) aracılığıyla işlenirler.


public interface IDomainEvent { }

public class SiparisOluşturulduEvent : IDomainEvent
{
    public Guid SiparisId { get; }
    public Guid MusteriId { get; }
    public decimal ToplamFiyat { get; }
    public DateTime OluşturulmaTarihi { get; }

    public SiparisOluşturulduEvent(Guid siparisId, Guid musteriId, decimal toplamFiyat, DateTime olusturulmaTarihi)
    {
        SiparisId = siparisId;
        MusteriId = musteriId;
        ToplamFiyat = toplamFiyat;
        OluşturulmaTarihi = olusturulmaTarihi;
    }
}

Entegrasyon Olayları (Integration Events) Nedir?

Entegrasyon Olayları, farklı Bounded Context'ler veya farklı mikroservisler arasında iletişim kurmak için kullanılır. Bir entegrasyon olayı, bir bağlamdaki bir değişikliğin diğer bağlamlar için de önemli olduğunu ve onların tepki vermesi gerektiğini belirtir. Örneğin, "Sipariş Yönetimi" servisindeki bir SiparişOluşturuldu domain olayı, "Ödeme" servisine OdemeTalebiOluşturuldu entegrasyon olayını tetikleyebilir. Entegrasyon olayları, genellikle bir mesaj kuyruğu (RabbitMQ, Kafka, Azure Service Bus vb.) aracılığıyla asenkron olarak iletilir.

Entegrasyon olayları, dağıtık sistemlerdeki nihai tutarlılığı (eventual consistency) sağlamanın anahtarıdır. Bir servis bir entegrasyon olayını yayımladığında, diğer servislerin bu olayı işleyip işlemeyeceğini veya ne zaman işleyeceğini garanti etmez, sadece olayı duyurur.


// Entegrasyon olayları genellikle daha geneldir ve birden fazla servisi ilgilendirir.
public class SiparisOlusturulduIntegrationEvent
{
    public Guid SiparisId { get; }
    public Guid MusteriId { get; }
    public IEnumerable Urunler { get; }
    public decimal ToplamTutar { get; }

    public SiparisOlusturulduIntegrationEvent(Guid siparisId, Guid musteriId, IEnumerable urunler, decimal toplamTutar)
    {
        SiparisId = siparisId;
        MusteriId = musteriId;
        Urunler = urunler;
        ToplamTutar = toplamTutar;
    }
}

public class UrunBilgisi
{
    public Guid UrunId { get; set; }
    public int Miktar { get; set; }
}

İki Tür Olay Arasındaki Farklar ve Kullanım Senaryoları

Aşağıdaki tablo, domain olayları ve entegrasyon olayları arasındaki temel farkları özetlemektedir:

Özellik Domain Olayları Entegrasyon Olayları
Kapsam Aynı Bounded Context/Servis içinde Farklı Bounded Context'ler/Servisler arasında
Amaç İç tutarlılık, yan etkileri yönetme Servisler arası iletişim, nihai tutarlılık
İletişim Genellikle senkron, in-process (MediatR gibi) Asenkron, mesaj kuyrukları (RabbitMQ, Kafka)
Teslim Garantisi Genellikle güçlü (işlem içinde) At least once, nihai tutarlılık
Veri İçeriği Domain modeline özgü, zengin Servisler arası anlaşmayı sağlayan, daha az detaylı

Mesaj Kuyrukları ve Olay Veriyolları (Message Buses)

Olay tabanlı mimarinin temel taşı, olayların güvenilir ve asenkron bir şekilde iletilmesini sağlayan mesajlaşma altyapısıdır. Bu altyapı genellikle mesaj kuyrukları veya olay veriyolları (message buses) şeklinde karşımıza çıkar.

Neden Mesaj Kuyrukları Kullanmalıyız?

Mesaj kuyrukları, dağıtık sistemlerde iletişimi sağlamak için kritik öneme sahiptir. Temel nedenler şunlardır:

  • Asenkron İletişim: Gönderici, mesajı gönderdikten sonra alıcının mesajı işleyip işlemediğini beklemez. Bu, sistemin genel yanıt süresini iyileştirir.
  • Yük Dengeleme ve Ölçeklenebilirlik: Bir kuyruğa gelen mesajlar, birden fazla tüketici tarafından paralel olarak işlenebilir. Bu, sistemin yoğun yüklere daha iyi dayanmasını sağlar.
  • Dayanıklılık ve Güvenilirlik: Mesajlar, tüketiciler onları işleyene kadar kuyrukta kalır. Tüketici arızalansa bile mesajlar kaybolmaz ve sistem yeniden ayağa kalktığında işlenmeye devam eder.
  • Ayırma (Decoupling): Üreticiler ve tüketiciler birbirlerinden bağımsız olarak geliştirilebilir, dağıtılabilir ve yönetilebilir.

Popüler Mesaj Kuyruğu Teknolojileri (.NET Ekosisteminde)

.NET geliştiricileri için birçok güçlü mesaj kuyruğu teknolojisi mevcuttur:

  • RabbitMQ: Açık kaynaklı, popüler bir mesaj broker'ıdır. AMQP protokolünü kullanır ve esnek yönlendirme, dayanıklılık ve yüksek performans sunar. .NET için RabbitMQ .NET client mevcuttur.
  • Apache Kafka: Yüksek performanslı, dağıtık bir akış platformudur. Özellikle büyük veri akışlarını işlemek ve olay günlüğü (event log) tutmak için tasarlanmıştır. .NET için Confluent.Kafka gibi client'lar bulunur.
  • Azure Service Bus: Microsoft Azure bulut platformunun bir parçasıdır. Yönetilen bir mesajlaşma hizmeti olup, yüksek güvenilirlik, gelişmiş özellikler (mesaj oturumları, zamanlanmış mesajlar) sunar.
  • Amazon SQS/SNS: AWS ekosistemindeki mesajlaşma hizmetleridir. SQS (Simple Queue Service) kuyruk tabanlı, SNS (Simple Notification Service) ise yayınlama/abone olma modeline dayalıdır.
  • MassTransit / NServiceBus: Bu kütüphaneler, .NET uygulamalarında mesajlaşma altyapısını soyutlayan ve kolaylaştıran yüksek seviyeli çerçevelerdir. RabbitMQ, Azure Service Bus gibi farklı mesaj broker'larını desteklerler ve dağıtık işlem yönetimi, yeniden denemeler, hata kuyrukları gibi gelişmiş özellikler sunarlar.

Olay Veriyolu (Event Bus) Uygulamaları

Bir olay veriyolu (event bus), olay üreticileri ile tüketicileri arasındaki iletişimi soyutlayan bir arayüzdür. Bu, özellikle domain olayları için servis içi (in-process) iletişimi yönetmek için kullanışlıdır. .NET'te MediatR gibi kütüphaneler, bu tür bir olay veriyolu işlevselliğini sağlayabilir. Entegrasyon olayları için ise genellikle MassTransit veya NServiceBus gibi daha kapsamlı kütüphaneler veya doğrudan mesaj kuyruğu client'ları kullanılır.


// Basit bir In-Process Event Bus Arayüzü
public interface IEventBus
{
    Task PublishAsync(TEvent @event) where TEvent : IDomainEvent;
    void Subscribe() 
        where TEvent : IDomainEvent
        where THandler : IEventHandler;
}

// Bir MediatR kullanımı örneği (IEventBus yerine)
// MediatR, Notification Pattern ile IDomainEvent'leri dispatch edebilir.
public class SiparisService
{
    private readonly IMediator _mediator;

    public SiparisService(IMediator mediator)
    {
        _mediator = mediator;
    }

    public async Task SiparisOlustur(SiparisOlusturCommand command)
    {
        // ... Sipariş oluşturma mantığı ...
        var siparis = new Siparis(command.MusteriId, command.Urunler);
        // ... Sipariş veritabanına kaydedilir ...

        // Domain olayını yayımla
        await _mediator.Publish(new SiparisOluşturulduEvent(siparis.Id, siparis.MusteriId, siparis.ToplamFiyat, DateTime.UtcNow));
    }
}

// Domain Olayı İşleyicisi
public class SiparisOluşturulduEventHandler : INotificationHandler
{
    public Task Handle(SiparisOluşturulduEvent notification, CancellationToken cancellationToken)
    {
        Console.WriteLine($"Sipariş {notification.SiparisId} oluşturuldu. Müşteri: {notification.MusteriId}");
        // Stok güncelleme, bildirim gönderme gibi yan etkiler burada tetiklenebilir.
        return Task.CompletedTask;
    }
}

Olay Tabanlı Mimariyi Tasarlama İlkeleri

Olay tabanlı bir mimari tasarlarken dikkat edilmesi gereken bazı önemli ilkeler vardır. Bu ilkeler, sisteminizin sağlam, güvenilir ve sürdürülebilir olmasını sağlar.

Olayların Tasarımı ve Veri Modeli

Olaylar, sistemdeki önemli durum değişikliklerini temsil ettiğinden, doğru tasarlanmaları kritik öneme sahiptir. Bir olay, meydana gelen olayı açıklayan bir isimle adlandırılmalıdır (geçmiş zaman kipiyle, örn: SiparişOluşturuldu, UrunStokGuncellendi). Olayın içeriği, olayı işlemek için gerekli tüm verileri içermelidir, ancak gereksiz detaylardan kaçınılmalıdır. Olaylar değişmez (immutable) olmalıdır, yani yayımlandıktan sonra içeriği değiştirilemez. Bu, olayların birer gerçek olarak kabul edilmesini ve tutarlılığını garanti eder.

Atomiklik ve Tutarlılık (Eventual Consistency)

Dağıtık sistemlerde "atomik işlem" (atomic transaction) kavramı, monolitik sistemlerdeki gibi kolayca sağlanamaz. Olay tabanlı mimaride genellikle "nihai tutarlılık" (eventual consistency) ilkesi benimsenir. Bu, bir olayın yayımlandıktan sonra, ilgili tüm tüketicilerin bu olayı işleyip sistemin nihai olarak tutarlı bir duruma gelmesinin biraz zaman alabileceği anlamına gelir. Bu gecikme, sistemin ölçeklenebilirliğini ve esnekliğini artırırken, geliştiricilerin bu durumu göz önünde bulundurarak uygulamalarını tasarlamalarını gerektirir. Örneğin, bir sipariş oluşturulduğunda stok hemen güncellenmeyebilir, ancak kısa bir süre sonra güncellenecektir.

Hata Yönetimi ve Idempotency

Mesajlaşma sistemlerinde mesajların "en az bir kez" teslim edilmesi garantisi yaygındır. Bu, aynı mesajın birden fazla kez teslim edilebileceği anlamına gelir. Bu durumu yönetmek için olay tüketicilerinin "idempotent" olması gerekir. Idempotent bir işlem, aynı girdilerle birden fazla kez çağrıldığında sistem üzerinde aynı etkiyi yaratır. Örneğin, bir stok azaltma işlemi, aynı sipariş için birden fazla kez çağrılsa bile stoğu sadece bir kez azaltmalıdır. Bu genellikle benzersiz bir işlem kimliği (transaction ID) kullanarak veya işlem durumunu kontrol ederek sağlanır.


// Idempotency örneği: İşlenmiş olayları takip etme
public class StokGuncelleEventHandler : IEventHandler
{
    private readonly IProcessedEventsRepository _processedEventsRepository;

    public StokGuncelleEventHandler(IProcessedEventsRepository processedEventsRepository)
    {
        _processedEventsRepository = processedEventsRepository;
    }

    public async Task Handle(SiparisOluşturulduIntegrationEvent @event)
    {
        // Olayın daha önce işlenip işlenmediğini kontrol et
        if (await _processedEventsRepository.IsEventProcessedAsync(@event.SiparisId, nameof(StokGuncelleEventHandler)))
        {
            Console.WriteLine($"Olay {@event.SiparisId} daha önce işlenmiş. Atlanıyor.");
            return; // Olay zaten işlenmiş, tekrar işlemeye gerek yok.
        }

        // Stok güncelleme mantığı
        Console.WriteLine($"Sipariş {@event.SiparisId} için stok güncelleniyor.");
        // ... stok azaltma işlemi ...

        // Olayın işlendiğini işaretle
        await _processedEventsRepository.MarkEventAsProcessedAsync(@event.SiparisId, nameof(StokGuncelleEventHandler));
    }
}

C# ve .NET'te Uygulama Örnekleri

Olay tabanlı mimariyi .NET uygulamalarında hayata geçirmek için çeşitli yaklaşımlar ve kütüphaneler mevcuttur. İşte bazı temel uygulama örnekleri.

Basit Bir Domain Olayı Tanımlama

Daha önce gösterildiği gibi, bir domain olayı basit bir POCO (Plain Old CLR Object) olabilir ve genellikle bir arayüzü uygular.


// IDomainEvent arayüzü (marker interface)
public interface IDomainEvent { }

// Gerçek bir domain olayı sınıfı
public class UrunFiyatiDegistiEvent : IDomainEvent
{
    public Guid UrunId { get; }
    public decimal EskiFiyat { get; }
    public decimal YeniFiyat { get; }
    public DateTime DegisimTarihi { get; }

    public UrunFiyatiDegistiEvent(Guid urunId, decimal eskiFiyat, decimal yeniFiyat, DateTime degisimTarihi)
    {
        UrunId = urunId;
        EskiFiyat = eskiFiyat;
        YeniFiyat = yeniFiyat;
        DegisimTarihi = degisimTarihi;
    }
}

Olay Yayımlama ve Tüketme Mekanizması

Domain olayları için genellikle in-process bir olay veriyolu kullanılır. MediatR, bu konuda oldukça popüler bir kütüphanedir. Entegrasyon olayları için ise bir mesaj kuyruğu client'ı veya MassTransit gibi bir soyutlama kütüphanesi tercih edilir.


// MediatR ile Domain Olayı Yayımlama (Publishing)
// Bir servis içinde
public class UrunService
{
    private readonly IMediator _mediator;

    public UrunService(IMediator mediator)
    {
        _mediator = mediator;
    }

    public async Task FiyatGuncelle(Guid urunId, decimal yeniFiyat)
    {
        // ... Ürünü veritabanından çek, eski fiyatı al ...
        decimal eskiFiyat = 100m; // Örnek
        // ... Fiyatı güncelle, veritabanına kaydet ...

        // Domain olayını yayımla
        await _mediator.Publish(new UrunFiyatiDegistiEvent(urunId, eskiFiyat, yeniFiyat, DateTime.UtcNow));
    }
}

// MediatR ile Domain Olayı Tüketme (Handling)
// Bir handler sınıfı
public class UrunFiyatiDegistiEventHandler : INotificationHandler
{
    public Task Handle(UrunFiyatiDegistiEvent notification, CancellationToken cancellationToken)
    {
        Console.WriteLine($"Ürün {notification.UrunId} fiyatı {notification.EskiFiyat}'tan {notification.YeniFiyat}'a değişti.");
        // Fiyat değiştiğinde yapılacak diğer işlemler (örn: indirimleri güncelle, bildirim gönder)
        return Task.CompletedTask;
    }
}

RabbitMQ ile Entegrasyon Olayları (Konsept)

Entegrasyon olayları için RabbitMQ gibi bir mesaj broker'ı kullanılır. MassTransit gibi kütüphaneler, bu süreci basitleştirir.


// MassTransit ile Entegrasyon Olayı Yayımlama
public class SiparisService
{
    private readonly IBus _bus; // MassTransit IBus instance'ı

    public SiparisService(IBus bus)
    {
        _bus = bus;
    }

    public async Task SiparisTamamlandi(Guid siparisId, Guid musteriId, decimal toplamTutar)
    {
        // ... Siparişin tamamlandığına dair işlemler ...

        // Entegrasyon olayını yayımla
        await _bus.Publish(new SiparisTamamlandiIntegrationEvent
        {
            SiparisId = siparisId,
            MusteriId = musteriId,
            ToplamTutar = toplamTutar,
            TamamlanmaTarihi = DateTime.UtcNow
        });
    }
}

// MassTransit ile Entegrasyon Olayı Tüketme
public class SiparisTamamlandiConsumer : IConsumer
{
    public Task Consume(ConsumeContext context)
    {
        var @event = context.Message;
        Console.WriteLine($"Entegrasyon Olayı: Sipariş {@event.SiparisId} tamamlandı. Müşteri: {@event.MusteriId}");
        // Örneğin, müşteriye e-posta gönder, muhasebe kaydı oluştur vb.
        return Task.CompletedTask;
    }
}

// Startup.cs veya Program.cs'de MassTransit konfigürasyonu
// builder.Services.AddMassTransit(x =>
// {
//     x.AddConsumer();
//     x.UsingRabbitMq((context, cfg) =>
//     {
//         cfg.Host("rabbitmq://localhost");
//         cfg.ReceiveEndpoint("siparis-tamamlandi-queue", e =>
//         {
//             e.ConfigureConsumer(context);
//         });
//     });
// });

Avantajları, Zorlukları ve Çözümler

Olay tabanlı mimarinin sunduğu pek çok fayda olsa da, beraberinde getirdiği bazı zorluklar da vardır. Bu zorlukları anlamak ve bunlara yönelik çözümler geliştirmek, başarılı bir EDA uygulaması için hayati öneme sahiptir.

Olay Tabanlı Mimarinin Sağladığı Faydalar


Yorumlar
İçeriği beğendiniz mi? Bir tartışma başlatın veya görüşlerinizi paylaşın.
Yorum Yaz

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

E-posta Bülteni
Yazılım Topluluğuna Katılın
En son güncellemeleri, yaratıcı ipuçlarını ve özel kaynakları doğrudan e-posta kutunuza alın. Tasarım ve inovasyonun geleceğini birlikte keşfedelim.