.Net Core ve MediatR ile CQRS Pattern Kullanımı

Hakan Topuz
3 min readDec 12, 2020

Merhabalar,

Bu yazımda CQRS pattern kullanımına değineceğim.Bu pattern’i kullanırken .Net Core Web Api projesi üzerinde MediatR paketinden faydalanacağım.

Öncelikle CQRS pattern ile alakalı biraz bilgi sahibi olalım.

CQRS(Command Query Responsibility Segregation) Nedir?

İsminden de anlaşılacağı üzere command ve querylerin ayrılması prensibine dayanır.

Command’tan kasıt nesnelerin durumunu değiştiren işlemler diyebiliriz.

Query ise, nesnenin durumunu değiştirmeyen, geriye bir nesne veya sonuç döndüren işlemlerdir.

Bu pattern’in temel prensibi; bir metot, bir nesnenin durumunu değiştirmelidir yada geriye bir değer dönmelidir.İkisini birden yapmamalıdır.

CQRS, verileri okumak ve yazmak için ayrı ayrı modeller kullanır.Komutlar veri(domain) bazlı değil göreve dayalı olmalıdır.Query’ler asla veritabanını değiştirmez.

Böylelikle modellerin tam olarak ne iş yaptığıyla alakalı bilgi sahibi oluruz.Daha okunabilir, yapılandırılmış ve ölçeklenebilir bir yapı elde etmiş oluruz.Bu tür ayrımlar sayesinde performans ölçümleri, okuma ve yazma işlemleri için yük ölçümleri daha kolay yapılabilir.

CQRS Neden ve Ne Zaman Kullanılmalı?

Kompleks ve değişken iş kurallarının, veri yapılarının olduğu projelerde kullanılabilir.Zira bizi karmaşık yapılardan, domain logic işlemlerinden kurtaracaktır.

Command-Query ayrımı sayesinde daha performanslı sonuçlar elde edilebilir.

Takım halinde geliştirilen projeler için iş bölümünü kolaylaştırır.

Performans ölçümünü ve optimizasyonunu kolaylaştırır.Kod okunabilirliğini, ölçeklenebilirliği artırır.

CQRS pattern’i MediatR kütüphanesi ile beraber uygulamaya başlayalım.

MediatR; Mediator pattern’inin kullanılmasını sağlayan bir kütüphanedir.Biz örneğimizde bu kütüphaneyi CQRS pattern için, command query modelleri ve bu modelleri handle ederek işlemi gerçekleştirecek sınıflar arasındaki iletişimi, loosely coupled olarak tek bir noktadan sağlamak için kullanacağız.

Mediator pattern’den de kısaca bahsedecek olursak; aynı arayüz üzerinden türeyen nesneler arasındaki iletişimi, tek bir nokta üzerinden sağlamaya dayalı bir pattern’dir.İletişimi tek bir sınıf(Mediator) üzerinden sağladığı için gevşek bağlılık sağlar.Bu konuda en çok verilen örnek uçak ve kule örneğidir.Uçakların hepsi kule ile iletişime geçer, birbirleriyle doğrudan iletişime geçmezler.Bu örnekte, Mediator nesnesi kule, uçaklarda türeyen sınıflardır diyebiliriz.

Artık kodlama işlemine başlayabiliriz.Öncelikle MediatR kütüphanesini projemize dahil edelim.

MediatR ile kullanılacak Handler sınıflarını register etmek için aşağıdaki kod bloğunu Startup.cs sınıfındaki ConfigureServices metodunun içerisine ekliyoruz.Bu sayede “Project.Core” katmanındaki mediatR sınıflarını tek seferde register etmiş oluyoruz.

Daha sonra Query için model sınıfımızı oluşturalım.

Gördüğünüz gibi GetContractQuery sınıfı IRequest arayüzünden türüyor.Bu arayüz ile beraber içerisine, Query sınıfının dönüş tipini de belirtiyoruz.(ContractResult)

Şimdi Handler sınıfımızı oluşturalım.

Bütün handler sınıfları, IRequestHandler interface’ini implemente eder.Bu interface’in içerisine, kullanacağı model sınıfını(GetContractQuery) ve dönüş tipini(ContractResult) belirtiyoruz.

Şimdi de controller sınıfımıza bakalım.

IMediator interface’ini constructor injection ile alıyoruz.

Bu interface’in Send metoduna request modelimizi veriyoruz.Bu arayüz, gelen request tipine göre, bu request tipini kullanan IRequestHandler arayüzünü implemente eden Handler sınıfını yakalar.

Örneğimiz üzerinden anlatacak olursak, GetContractHandler sınıfı IRequestHandler<GetContractQuery,ContractResult> interface’ini implemente ederek, Request tipinin GetContractQuery olduğunu belirtir.IMediator’da bu handler’ı request tipinden yakalar.

Query tipinde bir request için örnek oluşturmuş olduk.Sınıfların daha anlaşılabilir olması için okuma işlemi yapan request sınıflarını mutlaka …Query, yazma işlemi yapan sınıfları ise …Command ile isimlendirmenizi öneririm.

MediatR sayesinde bütün Command ve Query requestlerini tek bir arayüz üzerinden kullanarak gevşek bağlılık prensini sağlamış olduk.CQRS prensibini uygulayarak, yukarıda bahsetmiş olduğum avantajları sağlamış olduk.

Son olarak bütün pattern’lerde söylendiği üzere şunu belirtmek isterim ki, bu pattern’de kullanmış olmak için değil ihtiyaca göre kullanılmalıdır.Karışık , kompleks Domain yapılarında kullanılabilir ki, öbür türlü kullanıldığında ancak daha karmaşık bir yapı ve iş yükü doğuracaktır.Bu da ekstra maliyet demektir.

Şimdilik bahsedeceklerim bu kadar.Öğrendikçe paylaşmaya devam edeceğim.

Sağlıcakla kalın.

Kaynak:

https://medium.com/@ducmeit/net-core-using-cqrs-pattern-with-mediatr-part-1-55557e90931b

https://www.gokhan-gokalp.com/cqrs-command-query-responsibility-segregation-nedir/

--

--