Yazılım Mimarileri ve Tasarım Desenleri Üzerine

MediatR Yerine ‘martinothamar/Mediator’ Kütüphanesini İnceleyelim

Merhaba,

Bu içeriğimizde MediatR kütüphanesine alternatif olarak değerlendirebileceğimiz martinothamar/Mediator kütüphanesini hem teorik hem de pratik olarak inceleyecek, MediatR yerine nasıl konumlandığını en net şekilde ele alıyor olacağız.

martinothamar/Mediator Nedir?

martinothamar/Mediator, .NET dünyasında MediatR’a bir alternatif olarak geliştirilen lightweight, performans odaklı ve allocation-free olan bir Mediator Pattern implementasyonu kütüphanesidir. MediatR’a çok benzer API yapısına sahip olsa da daha modern, source-generator altyapısına sahip ve AOT dostu bir yapıya sahiptir.

Amacı;

Ana özellikleri ise;

Kim tarafından geliştirilmiştir?
Kütüphanenin ana geliştiricisi Martin Othamar abimizdir. GitHub reposuda https://github.com/martinothamar/Mediator adresindedir.

.NET’de Kullanımı

Mediator kütüphanesini kullanabilmek için öncelikle gerekli paketleri
dotnet add package Mediator.Abstractions
ve
dotnet add package Mediator.SourceGenerator
talimatları eşliğinde ilgili projeye yükleyiniz.

Ardından Mediator yapılarını projeye dahil edebilmek için aşağıdaki gibi servis entegrasyonunu gerçekleştiriniz:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddMediator();

var app = builder.Build();

Bu işlemlerden sonra CQRS, Notification veya Pipeline Behavior davranışlarından hangisini uygulamak istiyorsanız aşağıdaki gibi çalışmalar gerçekleştirebilirsiniz:

Streaming Messages

Son olarak Mediator kütüphanesinin en az bilinen ama en güçlü diyebileceğim özelliği olan Streaming Messages özelliğini değerlendirelim.

Bu özellik; esasında adı üzerinde, klasik CQRS davranışındaki handler’ın tek bir response döndürmesinden ziyade, zaman içinde birden fazla sonuç üretmesi (stream) üzerine kurgulanmış davranışlar için geçerli bir çözüm sağlamaktadır.

Aşağıdaki örneği incelerseniz eğer;

    public sealed record StreamRequest : IStreamRequest<StreamResponse>;
    public sealed record StreamResponse(Guid Id);
    public sealed class StreamHandler : IStreamRequestHandler<StreamRequest, StreamResponse>
    {
        public async IAsyncEnumerable<StreamResponse> Handle(StreamRequest request, CancellationToken cancellationToken)
        {
            for (int i = 0; i < 5; i++)
            {
                await Task.Delay(1000, cancellationToken);
                yield return new StreamResponse(Guid.NewGuid());
            }
        }
    }

şeklinde teknik bir kuyguyla rahatlıkla uygulanabilmektedir.

Tabi kullanırken de aşağıdaki gibi bir endpoint’ten istifade edilebilir:

app.MapGet("/streaming-messages", async (IMediator mediator, [AsParameters] StreamRequest streamRequest) =>
{
    await foreach (var response in mediator.CreateStream(streamRequest))
        Console.WriteLine(response);
});

Farkındaysanız esasında bu özelliğin tüm altyapısı .NET’teki asenkron iterasyonel işlevlerin temeli olan IAsyncEnumerable<T> interface’ine göre yapılandırılmıştır. Haliyle parça parça veri aktarımları süreçlerinde CQRS benimsenmişse eğer bu streamin özelliği ile hızlıca gerekli aksiyonlar alınabilecektir. Böylece, özellikle büyük veri setlerinde, uzun süren işlemlerde ve real-time akışlarda ihtiyacı karşılayabilecek muazzam bir altyapı elimizin altındadır diyebiliriz. Bir yandan, bu özellik ile ilgili kütüphanenin MediatR’a fark yarattığını da söyleyebiliriz.

Nihai olarak;

MediatR ücretli olduktan sonra CQRS gibi önemli bir pattern’ı manuel uygulamayı öneren onlarca tavsiyeden sonra (ki bu pattern’ın nasıl manuel uygulanacağına dair teknik makaleyi yıllar önce ilk kaleme alan kişi olarak diyorum ki) martinothamar/Mediator kütüphanesinin aynı kullanım pratikleri eşliğinde daha elverişli bir altyapı sağladığını söyleyebilirim.

İlgilenenlerin faydalanması dileğiyle…
Sonraki yazılarımda görüşmek üzere…
İyi çalışmalar…

Not : Örnek çalışmaya aşağıdaki GitHub adresinden erişebilirsiniz.
https://github.com/gncyyldz/CQRS_With_martinothamar_Mediator_Example

Mobil sürümden çık