6 Eylül 2015 Pazar

Repository Design Pattern Nedir?

 Büyük projelerde kod yazmak kontrol açısından gerçekten zordur. Düzenli ve planlı yapılmadığı zaman proje kontrolden çıkabilir. Bunun sonucunda da tekrarlanan kodlarla veya metotlar arasında bulabilirsiniz kendinizi. Bu nedenle düzgün bir yapı oluşturarak onun üzerinde ilerlemek bence en güzel çözümdür.

 Büyük projelerde bu gibi durumların önüne geçebilmek için alt yapı aşamasında uygun bir yapı kurulması için dikkat edilmesi gereken şey design patternların kullanımıdır. Bu yazımda elimden geldiğince size ilk yazım olan Reporsitory Design Pattern'ını anlatacağım.




repository design pattern

Yukarıdaki resimden de anlaşılacağı gibi Repository Pattern veri merkezli uygulamalarda veriye erişimin ve yönetimin tek noktaya indirgenmesini sağlayan bir tasarım desenidir.

Şimdi Kod üzerinde bakalım : 

Ben WindowsForm application oluşturdum ve için entity Framework code first kullanarak uygulamamı gerçekleştirdim. 

İlk olarak modellerimi yani entitylerimi oluşturdum.

 public class Personel
    {
        [Key]
        public int PersonelId { get; set; }
        public string PersonelName { get; set; }
        public int DepartmentId { get; set; }
        [ForeignKey("DepartmentId")]
        public virtual Department Deparments { get; set; }
    }

public class Equipment
    {
        [Key]
        public int EquipmentId { get; set; }
        public string EquipmentName { get; set; }
        public int EquipmentType { get; set; }
    }

 public class Department
    {
        [Key]
        public int DepartmentId { get; set; }
        public string DepartmentName { get; set; }
        public List<Personel> Personels { get; set; }
    }

DbContext'im de şu şekilde.

  public class MyContexts : DbContext
    {
        public DbSet<Personel> Personels { get; set; }
        public DbSet<Equipment> Equipments { get; set; }
        public DbSet<Department> Departments { get; set; }
    }

Artık sıra geldi Repositorye. Ben ilk olarak bir interface oluşturuyorum. Tabi bu tercihe kalmış bir durum.

public interface IRepository<TEntity>
         where TEntity : class,new()
    {
        TEntity Get(Expression<Func<TEntity, bool>> filter = null);
        List<TEntity> GetList(Expression<Func<TEntity, bool>> filter = null);
        TEntity Add(TEntity entity);
        TEntity Update(TEntity entity);
        void Delete(TEntity entity);
    }

Ben sadece tek bir eleman getirme , liste getirme, ekleme, güncelleme ve silme işlemleri için yazdım. Siz isterseniz bunu daha da geliştirebilirsiniz.

Sıra geldi hem entitylerimin hemde context imin repositoryde kullanılmasına. Yani benim BaseRepository dediğim duruma.

 public class BaseRepository<TEntity, TContext> : IRepository<TEntity>
        where TEntity : class,new()
        where TContext : DbContext, new()
    {
        public TEntity Get(System.Linq.Expressions.Expression<Func<TEntity, bool>> filter = null)
        {
            using (var context = new TContext())
            {
                return filter == null
                    ? context.Set<TEntity>().FirstOrDefault()
                    : context.Set<TEntity>().FirstOrDefault(filter);
            }
        }

        public List<TEntity> GetList(System.Linq.Expressions.Expression<Func<TEntity, bool>> filter = null)
        {
            using (var context = new TContext())
            {
                return filter == null
                    ? context.Set<TEntity>().ToList()
                    : context.Set<TEntity>().Where(filter).ToList();
            }
        }

        public TEntity Add(TEntity entity)
        {
            using (var context = new TContext())
            {
                var addedEntity = context.Entry(entity);
                addedEntity.State = EntityState.Added;
                context.SaveChanges();

                return addedEntity.Entity;
            }
        }

        public TEntity Update(TEntity entity)
        {
            using (var context = new TContext())
            {
                var updatedEntity = context.Entry(entity);
                updatedEntity.State = EntityState.Modified;
                context.SaveChanges();

                return updatedEntity.Entity;
            }
        }

        public void Delete(TEntity entity)
        {
            using (var context = new TContext())
            {
                var deletedEntity = context.Entry(entity);
                deletedEntity.State = EntityState.Deleted;
                context.SaveChanges();
            }
        }
    }

Burada interface'imden gelen methodların gövdelerini yazdım hemde hangi DbContext'imi kullanacağımı belirttim.

Ve sıra geldi artık işlemlerimi Entitylerim yani kullanacağım sınıfların metotlarını yazmaya. Ben sadece Personel sınıfı ve Department sınıfı için yazdım.

Personel:

  public class PersonelRepository : BaseRepository<Personel, MyContexts>
    {
        
        public Personel GetPersonel(int personelId)
        {
            return Get(filter: t => t.PersonelId == personelId);
        }

        public List<Personel> GetPersonelList(int departmentId)
        {
            return GetList(filter: t => t.DepartmentId == departmentId);
        }

        public Personel AddPersonel(Personel personel)
        {
            return Add(personel);
        }

        public Personel UpdatePersonel(Personel personel)
        {
            return Update(personel);
        }

        public void DeletePersonel(Personel personel)
        {
            Delete(personel);
        }
    }

Department :

 public class DepartmentRepository:BaseRepository<Department, MyContexts>
    {
        public Department GetDepartment(int departmentId)
        {
            return Get(filter: t => t.DepartmentId == departmentId);
        }

        public List<Department> GetDepartmentList(int departmentId)
        {
            return GetList(filter: t => t.DepartmentId == departmentId);
        }

        public Department AddDepartment(Department department)
        {
            return Add(department);
        }

        public Department UpdateDepartment(Department department)
        {
            return Update(department);
        }

        public void DeleteDepartment(Department department)
        {
            Delete(department);
        }
    }

Artık bu repositoryleri projemde rahatlıkla çalıştırabilirim. Açtığım formda 3 adet buton koydum. Bunlar liste getir, ekle ve güncelle.

 public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        PersonelRepository personelRep = new PersonelRepository();
        DepartmentRepository departmentRep = new DepartmentRepository();
        private void btnGetir_Click(object sender, EventArgs e)
        {
            var p = personelRep.GetPersonelList(1);
        }

        private void btnEkle_Click(object sender, EventArgs e)
        {
            Department d = new Department() {DepartmentId=1,DepartmentName="Yazilim" };
            departmentRep.Add(d);

            Personel p = new Personel { PersonelName="Burak Karatatar",DepartmentId=1 };
            personelRep.AddPersonel(p);
            MessageBox.Show("Personel Eklendi");
        }

        private void btnGuncelle_Click(object sender, EventArgs e)
        {
           
        }
    }

Gördüğünüz gibi artık tek yapmamız gereken repository metotlarımıza parametreleri göndermek ve gerisini ayaklarımızı uzatarak izlemek :) Ayrıca bunun bize kazandırdığı bir avantajda işlem sırasında oluşabilecek hataları daha rahat kontrol edebilmemiz olacak. Çünkü artık işlemlerimiz tek bir yerden yani BaseRepository üzerinden gidip dönecek. Exception kontrolünü burada rahatlıkla yapabiliriz. Umarım faydalı bir yazı olmuştur...




2 yorum:

  1. Burak Bey Bende Bayram TATAR
    çok güzel bir konu olmuş.
    burada verileri formdaki textboxlardan nasıl alıp veritabanına kayıt edeöiliriz.

    YanıtlaSil