.Net Core ile GraphQLRepository Design Pattern Altyapısı

Adem Olguner
5 min readJan 19, 2020

--

Bir rivayete göre Repository Design Pattern, Design Pattern ailesi içerisinde en çok kullanılan pattern olduğu söylenir.

Veriye erişim ve yönetimin tek noktaya indirilmesini sağlayan bir tasarım desenidir.

Repository Pattern Faydaları

  • Maintainability (sonradan bakım kolaylığı) arttırır,
  • Unit-test yapabilmemizi kolaylaştırır,
  • Esnek bir mimari uygulamamızı sağlar,
  • Yeni gelecek modüller veya istenilen değişiklikleri kolayca entegre edebilmeyi sağlar,
  • Domain driven development’ın önünü açar.

Veri merkezli yazılımların iş katmanlarından veriye ulaşım işlemleri sırasında meydana gelen ve gözardı edilen bazı ayrıntılar, yazılımın ileriki aşamalarında önümüze bir çığ misali yığılıp kalmaktadır. Özellikle katmanlı mimaride geliştirilen yazılımlarda iş kuralları ve katmanlar, düzgün oluşturulmadığı takdirde bir işi N defa yapmak zorunda kalabiliriz. Ancak nesneye yönelik (object oriented) yapıların ilkelerinden biri de, bir kuralı bir kez belirleyip N kez çalıştırmaktır.

İş katmanında dikkat edilmesi gereken bazı kurallar vardır. Bunlar:

  • Kod tekrarlarından kaçınmak
  • Hata yakalamayı kolaylaştırmak
  • Kod yazımını ve okunuşunu kolaylaştırmak
  • Test edilebilir bir yapı kurgulamak

Repository pattern de bizi bu kurallara uymaya zorlamaktadır.

Bir uygulama üzerinden Bu tasarım kalıbını inceleyeceğiz.

Proje ve Katmanları oluşturmaya başlayalım.

Visual Studio 2019'u açıyoruz.

Blank Solution oluşturarak başlıyoruz.
(File => New => Project)

Projemizi isimlendiriyoruz ve kaydedeceğimiz yeri seçiyoruz.

Solution Project (NewspaperCoreGrapgQL)’e
Sağ Tık => Add => New Project

Şimdi API projemizi oluşturacağız.
Solution Project => Sağ tık => Add => New Project

ASP.NET Core Web Application seçeceğiz. Ardından çıkan ekranda API projesini seçeceğiz.

Nuget Paket Yöneticisinden altta görülen paketleri indireceğiz.
Paketler ve katman listesi şu şekildedir.

  • NewspaperCoreGrapgQL.Business (Business Katmanımızın Adı)
    - GraphQL (2.4.0) Versiyon değişebilir .(Nuget Paketi)
  • NewspaperCoreGrapgQL.Core (Ortak Katmanımızın Adı)
    - Microsoft.EntityFrameworkCore (2.1.0) Versiyon değişebilir.(Nuget Paketi)
  • NewspaperCoreGrapgQL.DataAccess (DataAccess Katmanımızın Adı)
    - Microsoft.EntityFrameworkCore.SqlServer(Nuget Paketi)
  • NewspaperCoreGrapgQL.GraphWebAPI (API Katmanımızın Adı)
    -GraphQL (2.4.0) Versiyon değişebilir . (Nuget Paketi)
    -GraphiQL (1.2.0) Versiyon değişebilir .(Nuget Paketi)

Proje katmanları oluşturulduktan sonra projeye ait Solution Explorer görünümü aşağıdaki gibi olacaktır.

  • Entities Katmanı içerisinde veritabanı nesnelerini oluşturuyoruz.
  • DataAccess Katmanı içerisinde veritabanı nesnelerinin Soyut (Interface), Somut (Concrete) sınıflarımızı ve DBContext nesnemizi oluşturuyoruz.
  • Core Katmanında diğer katmanlar için ortak ve diğer katmanlardan bağımsız altyapı işlemlerini yapacağız.

NOT : DataAccess Katmanında Post nesnesi için IPostDal somut (interface) sınıfında 5 adet metot tanımlayıp, PostDal somut (concrete) sınıfında IPostDal’i miras alıp metotların içerisini doldurmamız gerekiyor ve bu işlemi veritabanında bulunan tüm nesneler için yapmamız gerekiyor.

* Ortalama 20–25 tablo olduğunu varsayalım ve tümü için bu işlemleri yaptığımızı düşünelim bir hayli uzun ve yorucu olacaktır. Ancak kuracağımız Repository Tasarım Kalıbı ile bu işlem yükünü ortadan kaldırıyoruz.

Tüm bu işlemler için T tipinde Generic Type kullanarak IEntitiyRepository ve EntitiRepositoryBase nesnelerini oluşturuyoruz.

* Metot içlerini EntityRepositoryBase sınıfında dolduracağız.

TEntity => Veritabanı Nesnesi alıyoruz (Post,Category,Comment vb..)
TContext => Bir DbContext nesnesi alıyoruz. (NewspapaerDbContext)

Bu şekilde veritabanı nesneleri için (Veritabanında oluşturulan ve Entities Katmanında Models klasörü altındaki nesneler için işlemlerimiz hazır)

IEntityRepository içerisinde geriye T tipinde Entity nesnelerimiz dönüyor, gerçek hayat senaryolarında ise bir kaç tablonun join işlemi sonucu complex type nesnelerde geri döndürmek durumunda kalıyoruz. Bu durumda methodlarımızı DataAccess Katmanı içerisinde nesne interfaceleri (Soyut nesneler) içerisinde tanımlayıp ( somut nesneler ) haline getireceğiz.

Entities Katmanında ComplexType klasörü içerisinde bir nesne oluşturuyoruz. (PostTagDto) bir adet string tipinde özellik tanımlıyoruz (TagValueName).

Burada complex tip dedik ancak tek bir property oluşturduk !!!

PostTagDto nesnesine ait ihtiyaç doğrultusunda farklı propertyler eklenebilir şu an için benim ihtiyacım sadece TagValueName değeri olduğu için 1 adet tanımladım.

public interface ITagDal : IEntityRepository<Tag>

Bu şekilde ITagDal soyut sınıfına IEntityRepository<Tag> miras alarak daha önce yazılan 5 metot burada geçerli kılıyoruz .

ITagDal soyut sınıfı (interface) içerisinde geri dönüş tipi PostTagDto olan metot tanımlıyoruz.

Metodun içeriğini TagDal somut sınıfı içerisinde dolduruyoruz. Post nesnesine ait tag değerini PostTag tablosunda alabilmek için 3 tablonun join işlemini ihtiyaç duyarız ve geriye dönüş değeri olarak PostTagDto türünde olduğuna dikkat edelim.

Bu şekilde geriye farklı tabloların join işlemi sonucu farklı tipte (Veritabanında oluşturduğumuz nesneler Post,Category vb.. dışındaki tipler için) bu soyut sınıflarda metot imzaları oluşturup yazabiliriz.

Business katmanında ise iş kurallarını yazacağız.

Tag nesnesi üzerinden örneğimize devam edelim.

ITagService, Tag nesnesine ait iş kurallarının yazılmış olduğu soyut sınıfında şimdilik gerekli olan 5 adet EntityRepositoryBase nesnesinde bahsettiğimiz metotları ve ek olarak DataAccess katmanında (ITagDal) yazmış olduğumuz join işlemleri için yazılan GetPostTag metotlarından yararlanarak ihtiyacımız olan iş kurallarını oluşturacağız.

ITagService soyut sınıfını (Interface) miras alan TagManager nesnemizde metotların içeriğini dolduracağız.

Katmanlar ve işlemleri üzerinden geçelim.

  • Entities katmanı: Veritabanı nesnelerinin ve join işlemi sonucu complex tipte geri dönüş yapan nesnelerin tanımlandığı katmandır.
  • DataAccess Katmanı: Veritabanı işlemlerinin insert-update-delete gibi yapıldığı katmandur. Bu katman sadece Entities katmanını referans alacaktır.
  • Business Katmanı : Bu katman iş kurallarının ihtiyacı doğrultusunda gerekli olan işlemlerin yapıldığı katmandır. Business katmanı sadece DataAccess katmanını referans alacaktır (DataAccess katmanı kendi içerisinde Entities katmanını referans aldığı için Business katmanda tekrar Entities katmanını referans almaya gerek yoktur)

Proje katmanlarının bağımlılıkları aşağıdaki görsel şeklinde olacaktır.

Yazımızın devamı olarak graphql işlemlerini anlatacağız. GraphQL işlemleri için bu makaleden devam edebiliriz.

Yararlı olması dileğiyle. Başka bir yazıda görüşmek üzere.

--

--