31 Temmuz 2018 Salı

Tekrarlanan Kodları Generic Metota Çıkarma (Refactoring)

     S.a. Arkadaşlar,
     Her ay en az bir blog yazmaya özen gösteriyorum. Şuan yazmaya başladığımda farkettim ki ayın son günü :) Yeni iş , taşınma derken uzun bir süredir yazmak istediğim halde yazmakta zorlanıyordum. Neyse ki bugüne kısmet oldu. Bugün yazacağım konu generic metod ve refactoring ile ilgili. Yazdığım bir kaç action'un (metodun) birbirine benzediğini fark ettim. Onları ortak bir metoda alabilir miyim diye yola çıkarken bir de baktım ki bir yazı olacak bir şey ortaya çıkıvermiş.Ben de bu fırsatı kaçırmak istemedim :)

     İşe başlarken birbirine benzeyen 2metodumu daha sonra yaptığım düzeltmeleri anlatmaya çalışacağım. Daha güzel bir şekilde önerisi olan varsa düşüncelerinizi almak isterim
public PartialViewResult TanimTipGetir(int? id)
{
    TanimVM vm = new TanimVM();
    vm.TanimTipModel = _uow.Repository<TanimTipModel>().Table.Where(p => p.Id == id).FirstOrDefault() ?? new TanimTipModel();
    return PartialView("Partial/_TanimTipDoldur", vm);
}

public PartialViewResult UyeTipiGetir(int? id)
{
    UyeTipiVM vm = new UyeTipiVM();
    vm.UyeTipi = _uow.Repository<UyelikTipModel>().Table.Where(p => p.Id == id).FirstOrDefault() ?? new UyelikTipModel();
    return PartialView("Partial/_UyelikTipiDoldur", vm);
}


  Bu iki metodu ilk başta şöyle bir hale getirebildim.
private PartialViewResult VeriGetir<ModelVM, ModelIci>(int? id,string partialViewPathName) where ModelVM : new() where ModelIci : class, new()
{
 dynamic modelVM = new ModelVM();
 dynamic modelIci = new ModelIci();

 modelVM.modelIci = ((IEnumerable<dynamic>)_uow.Repository<ModelIci>().Table).Where(d => d.Id == id).FirstOrDefault() ?? new ModelIci();
 return PartialView(partialViewPathName, modelVM);
}


     Burada söylemek istediğim önemli bir şey kısıtlamaları iyi kullanmamız gerektiğidir. Burada ikili kısıtlama yaptık. Bununla ilgili de ayrıntılı bilgiyi buradan alabilirsiniz. Bu konuda bana yardımcı olan Burak Selim Hoca'ya da teşekkürlerimi iletmek isterim. 

   Daha sonra bu da kodun tek başına derlenmesine yetmedi. Bunun için IEnumerable<dynamic> yapısı ile cast ettik ve d.Id tanımlamasına bu şekilde izin verdik. Daha gerçeği rum time'de derlenmesini sağlıyor. Dynamic anahtar kelimesi intellisense özelliğini kapatıyor gibi düşünmek lazım belki de.

    Ayrıca dynamic modelVM diye tanımlanan yerde var tanımlaması yapmıştım, fakat var tanımlaması yaptığımda kod derlenmiyordu. Bir kaç gün önce okuduğum bir makalede dynamic anahtar sözcüğü ile yapmaya karar verdim.Bu sefer kod run time'de patladı. Run time'de modelVM içerisinde modelIci objesi olmadığı için hata fırlatıyordu. Bunun için ne yapabilirim diye baya düşündüm.

    Bu şekilde modelIci ile farklı modelVM'lerde tanımlamama yapamayacağımı anlayınca farklı bir yol seçtim. O da generic bir ModelVM yaptım ve onu kullanmaya karar verdim. Oluşturduğum modelVM aşağıdaki gibidir.
public class DinamikTanimlamaVM<T> : UyeBase where T : class,new()
 {
     public IEnumerable<T> DinamikTanimlamaList { get; set; }
     public T DinamikTanimlama { get; set; }
 }

    Daha sonra modelVM üzerinden gönderdiğim sınıfa rahatlıkla ulaşabildim. En son olarak geldiğim çözüm ise aşağıdaki gibidir.
 private ModelVM VeriGetirDL<ModelVM, ModelIci>(int? id) where ModelVM : new() where ModelIci : class, new()
 {
     dynamic modelVM = new ModelVM();
     modelVM.DinamikTanimlama = ((IEnumerable<dynamic>)_uow.Repository<ModelIci>().Table).Where(d => d.Id == id).FirstOrDefault() ?? new ModelIci();
     return modelVM;
 }

    Uzun süredir kod ağırlıklı yazı yazmıyordum. Bu yazımız böyle oldu. Tüm bu süreçte oldukça yoğun ve güzel şeyler öğrendim. Bunları da hem not alıp paylaşmak hem belki daha güzel önerileri olacak birileri olabilir diye paylaşmak istedim. Generic kodlar yazmak dileğiyle. Hoşça Kalın.

Hiç yorum yok:

Yorum Gönder