Dev Arksoft
  • Arksoft Developer Network
  • Ağustos 2023
    • Angularda DOM (Document Object Model) Manipülasyonu
    • Angular’da Routing
    • Representational State Transfer (REST)
    • .Net Framework için Local NugetPackage
    • Agile Nedir?
  • Temmuz 2023
    • Angular HTTP Interceptors
    • Angularda Promise ve Observable
    • Mongo DB Kullanımı
  • Haziran 2023
    • Angular Validators
  • Mayıs 2023
    • Docker Uzerine Redis Kurulumu ve .Net Core ile Redise Erişim
  • Nisan 2023
    • Angular 14 Componentler Arası İletişim
  • Şubat 2023
    • JMeter ile Performans Testi
  • Ocak 2023
    • Windows Giriş Ekranında C# Form Açmak
  • Temmuz 2022
    • Regular Expressions
  • Haziran 2022
    • RSA Şifreleme
    • AutoMapper Kullanımı
    • Permutasyon ve Kombinasyon
    • Generic Repository Pattern
    • Levenshtein Algoritması
    • HTML 5’e Giriş
    • Graph Yapılar
  • Mayıs 2022
    • IQueryable IEnumerable Farklar
    • Sıralama Algoritmaları
  • Şubat 2022
    • ADFS Custom 2FA Integration
    • Reacta Giriş ve Reactın Temel Prensipleri
    • TypeScript Kullanımı
    • Serialization Kullanımı
    • Log4Net Kullanımı
    • Collections Yapıları
    • Windows Service Projesini Debug Etme ve Harici Exe Çalıştırma
    • Culture ve DateTime Kullanımı
    • Reflection Kullanımı
    • Steganografi Teknikleri
    • ElasticSearch Kullanımı
    • SWAGGER ve JWT TOKEN BASED WEBAPI Kullanımı
    • LINQ Komutları Kullanımı
    • Image Processing İşlemleri Kullanımı
Powered by GitBook
On this page
  1. Haziran 2022

Generic Repository Pattern

Husamettin Elalmis

PreviousPermutasyon ve KombinasyonNextLevenshtein Algoritması

Last updated 2 years ago

Generic Repository Pattern

Merhaba arkadaşlar, bu yazıda sizlere Generic Repository Pattern kavramından bahsecedeğim.

Repository Pattern Nedir?

  • Veriye erişim ve yönetimi kapsamında, tek bir noktadan yönetilebilen yapılara Repository Pattern diyoruz.

  • Repository Pattern kullanmak, projelerimizin rahat ve kolay ölçeklenebilmesini, büyüyebilmesini sağlar.

  • Repository Patternin kullanılmadığı durumlarda, yazılan kodlar tekrara girme eğilimine girer ve kod spaghetti (baştan aşağıya karışık) yapıya doğru gider. Yönetilemez hale gelir.

Generic Repository Pattern Nedir?

  • Generic, "tipi değişen" demektir.

  • Generic repository pattern dediğimizde, repositorymizin içerisindeki kullanılan Tip nesnesinin değişebileceğini anlarız. Yani, merkezi bir repository yapımız var iken, bu merkezi repository desenimiz, t_Users tipi alabileceği gibi t_Customers tipi de alabilir olduğunu anlarız.

  • Bu tarz generic yapılar, mimari anlamda projeye büyük kolaylıklar sağlar.

  • Generic yapılar, mimari kodlamada olmazsa olmazlardandır, hayal gücü ile doğru orantılı olarak genişlemeye müsaiddir.

Senaryo MSSQL Tablo Yapısı

  • PhoneBookDB veritabanı oluşturdum

  • t_Users tablosu oluşturdum

  • Amacımız, bu DBye, Generic Repository Pattern yaklaşımı ile ulaşmak olacak.

Program

PhoneBookDBContext.cs

using GenericRepositoryArge.Base;

using Microsoft.EntityFrameworkCore;

namespace GenericRepositoryArge.Context

{

// dbContextimiz public class PhoneBookDbContext : DbContext

{

// constructorumuz public PhoneBookDbContext(DbContextOptions<PhoneBookDbContext> options) : base(options)

{

}

// tablolarımız public DbSet<t_Users> t_Users { get; set; }

}

}

IEntityBase.cs

using GenericRepositoryArge.Context;

using Microsoft.EntityFrameworkCore;

using System;

using System.ComponentModel.DataAnnotations;

using System.Linq;

using System.Threading.Tasks;

namespace GenericRepositoryArge.Base

{

// base interfaceimiz public interface IEntityBase

{

// buraya ihtiyacımıza göre eklemeler yapabiliriz

}

// generic classımız public class EntityBase<TKey> : IEntityBase

{

// primary key kolonumuz, türü generic

[Key]

public TKey Id { get; set; } // tüm tablolarda ortak olan kolonlar public DateTime CreatedAt { get; set; } // .. varsa diğerleri

}

// t_users tablomuz, primary key türü integer public class t_Users : EntityBase<int>

{

// tablo kolonlarımız public string UserName { get; set; } // .. varsa diğer kolonlar

}

// generic interfaceimiz, tablo ve primarykey türü alır, baseEntityden türemek zorundadır // tüm tablolar bu interface üzerinden türeyebilir public interface IRepositoryBase<TEntity, TKey> where TEntity : EntityBase<TKey>

{

// tüm kayıtları döndürecek olan methodumuz, expression filter parametre destekli, IQueryable döndürüyoruz

IQueryable<TEntity> GetAll(Func<TEntity, bool> filter = null);

// Idye göre kayıt getir (primary key türü generic)

Task<TEntity> GetById(TKey id);

// tabloya insert eden method

Task<TEntity> Insert(TEntity entity);

// satırı update eden method

Task<TEntity> Update(TEntity entity);

// tablodan veri silen method

Task<TEntity> Delete(TEntity entity);

// .. varsa diğer methodlar

}

// repository classımız public class RepositoryBase<TEntity, TKey> : IRepositoryBase<TEntity, TKey> where TEntity : EntityBase<TKey>

{

// dbContext nesnemiz, bu repository bu context ile muhatap olacak private readonly DbContext context; // constructor public RepositoryBase(DbContext context)

{

this.context = context;

}

// generic delete methodumuz, virtual yapmamın sebebi ezilebilir olmasını istememdir public virtual Task<TEntity> Delete(TEntity entity)

{

context.Set<TEntity>().Remove(entity);

context.SaveChanges();

return Task.FromResult(entity);

}

// generic GetAll methodumuz, virtual yapmamın sebebi ezilebilir olmasını istememdir public virtual IQueryable<TEntity> GetAll(Func<TEntity, bool> filter = null)

{

// performanslı getirsin diye AsNoTracking kullanıldı return (filter == null) ? context.Set<TEntity>().AsNoTracking() : context.Set<TEntity>().AsNoTracking().Where(filter).AsQueryable();

}

// generic getById methodumuz, virtual yapmamın sebebi ezilebilir olmasını istememdir public virtual Task<TEntity> GetById(TKey id)

{

return Task.FromResult(context.Set<TEntity>().AsNoTracking().FirstOrDefault(x => x.Id.Equals(id)));

}

// generic insert methodumuz, virtual yapmamın sebebi ezilebilir olmasını istememdir public virtual async Task<TEntity> Insert(TEntity entity)

{

await context.Set<TEntity>().AddAsync(entity); await context.SaveChangesAsync(); return entity;

}

// generic update methodumuz, virtual yapmamın sebebi ezilebilir olmasını istememdir public virtual async Task<TEntity> Update(TEntity entity)

{

context.Set<TEntity>().Update(entity);

await context.SaveChangesAsync(); return entity;

}

}

// t_Users tablosuna ilişkin arayüz repositorymiz. Tüm repositoryler bundan türetilir. public interface IUserRepository : IRepositoryBase<t_Users, int>

{

}

// t_Users repositorymiz. Primary key tipi integer, tablomuz t_users anlamındadır. public class UserRepository : RepositoryBase<t_Users, int>, IUserRepository

{

// constructorumuz public UserRepository(PhoneBookDbContext context) : base(context)

{

// bu repository tanımlanırken buraya context parametre geçilir, bu context bu repository için muhatap olur.

}

}

}

Program.cs

using GenericRepositoryArge.Base;

using GenericRepositoryArge.Context;

using Microsoft.EntityFrameworkCore;

using Microsoft.Extensions.DependencyInjection;

using System;

namespace GenericRepositoryArge

{

class Program

{

static void Main(string[] args)

{

Test();

Console.WriteLine("ok");

Console.ReadLine();

}

private async static void Test()

{

string conStr = @"Data Source=DESKTOP-PBV06FI\Server2014; Initial Catalog=PhoneBookDB; Persist Security Info=True; Integrated Security=SSPI;pooling=true;"; // dependency injection setupumuz // SQL server kullanacağımızı söylüyoruz, PhoneBookDbContext'i kullanacağız, // interface'e karşılık hangi Repositorynin ayağa kalkacağını belirliyoruz var serviceProvider = new ServiceCollection()

.AddDbContext<PhoneBookDbContext>(x => x.UseSqlServer(conStr))

.AddScoped<IUserRepository, UserRepository>()

.BuildServiceProvider();

// userRepository oluştur var userRepo = serviceProvider.GetService<IUserRepository>(); // entity oluştur

t_Users entity = new t_Users() { UserName = "Hüsamettin4", CreatedAt = DateTime.Now };

Console.WriteLine("Kayıt eklendi");

// kaydet var res2 = await userRepo.Insert(entity); // verileri getir var res = await userRepo.GetAll().ToListAsync(); // verileri yaz foreach (var item in res)

{

Console.WriteLine($"{item.Id} {item.UserName} {item.CreatedAt}");

}

}

}

}

Sonuç

  • Bu dokumanda Generic Repository Pattern yapısını uygulamalı görmüş olduk

  • Dependency Injection kavramını kullanmış olduk

  • Her tablo için Repository oluşturulabilir, tüm repositoryler merkezi yerden beslenir (Generic Repository Pattern)

  • Bu yapı, her türlü projede mimari olarak kullanılabilir, ölçeklenebilir, genişletilebilir.

    • MSSQL ve POSTGRE providerlari ile çalışılabilir

    • ORACLE entegrasyonu yapılabilir (İlave kodlamalar ile)

    • Ado.Net mimarisi entegre edilebilir

    • Dapper mimarisi entegre edilebilir

Saygılarımla,

Hüsamettin ELALMIŞ – 11.06.2022

husamettin.elalmis@arksoft.com.tr