19 Nisan 2015 Pazar

Fluent NHibernate ile Kullanıcı Tanımlı Tipler Kullanmak



    Herkese merhabalar.


    Bugün sizlere, Fluent NHibernate kullanırken kullanıcı tanımlı tiplerin nasıl kullanıldığından bahsedeceğim. Kullanıcı tanımlı tip derken ne demek istediğimi enum(enumeration) kavramını açıklayarak ifade etmek istiyorum. Program içerisinde kullanılan sabitlerin anlamlandırılması ile sabitlere isim vererek bir grup altında toplayabiliriz. İşte bu gruplara enum(enumaretion) denmektedir. Enum içerisindeki elemanlar, dizilerdeki gibi 0 sıra numarasından başlamak üzere sıralanır [1]. Enum kullanımını daha iyi anlamamız açısından, enum denilince akla gelen klasik örneği sizlerle paylaşmak istiyorum.

   Örneğin; programımızda haftanın günlerini kullanmak isteyelim. Bu günler ile karmaşık işlemler yapmak isteyelim. Bunun için  her güne sayısal değer vermemiz bizim işimizi görecektir. Pazartesi, Salı, Çarşamba, Perşembe, Cuma, Cumartesi, ve Pazar’a 0,1,2,3,4,5 ve 6 tam sayı değerlerini tanımlamamız yeterli olacak ve bu tam sayılar üzerinden işlemlerimizi gerçekleştireceğiz. Öte yandan, sıfırı (0) kullandıktan ve bir süre sonra koda baktığımızda sıfırın Pazartesi gününü ifade ettiğini hatırlayamayabiliriz. Bu durumda, C# bizlere güzel bir çözüm sunar. Bu çözümde; değerlerin grup sembolik bir ad ile bildirilebileceği "enum" anahtar sözcüğü kullanılır [2]. Enumeration türünü aşağıdaki şekilde tanımlayabiliriz.

 Enum HaftaGunler  
 {  
 Pazartesi,  
 Sali,  
 Carsamba,  
 Persembe,  
 Cuma,  
 Cumartesi,  
 Pazar  
  }  

Enumeration türünü yukarıdaki şekilde tanımladıktan sonra aşağıdaki şekilde erişebiliriz.


 HaftaGunler gun = HaftaGunler.Pazar;  
 MessageBox.Show(gun.ToString());  

Böylelikle, mesaj kutumuzda "6" yazacaktır. Haftanın günlerinin hepsini birden almak istersek .GetNames() metodunu kullanırız. Bu metot yardımıyla enum içerisinde kullandığımız değerleri  string formatında bir dizide aşağıdaki şekilde kullanabiliriz [2].

  string[] gunler = Enum.GetNames(typeof(HaftaGunler));  

    Şimdi de enumların Fluent NHibernate'teki kullanımına bakalım. Fluent NHibernate ile özel bir kullanıcı tipi tanımlanmak istendiğinde, IUserType arayüzünden kalıtılmış bir sınıf ile ilgili tipi tanımlayabiliriz [3]. Aşağıdaki kod örneğinde, lisans ve yüksek lisans öğrenci tipini içeren enum kullanılmıştır [4].

 public enum Ogrencitipi  
 {  
   Lisans,  
   Yukseklisans  
 }  

 using System;  
 using System.Data;  
 using NHibernate.SqlTypes;  
 using NHibernate.UserTypes;  
 namespace YourNamespace.Persistence.Mappings.CustomTypes  
 {  
   public class OgrencitipiMap : IUserType  
   {  
     new public bool Equals(object x, object y)  
     {  
       return object.Equals(x, y);  
     }  
     public int GetHashCode(object x)  
     {  
       return x.GetHashCode();  
     }  
     public object NullSafeGet(IDataReader rs, string[] names, object owner)  
     {  
       object r = rs[names[0]];  
       var value = (string)r;  
       if (string.IsNullOrEmpty(value))  
         throw new Exception("Geçersiz!");  
       switch (value)  
       {  
         case "L":  
           return Ogrencitipi.Lisans;  
         case "Y":  
           return Ogrencitipi.Yukseklisans;  
         default:  
          throw new Exception("Geçersiz öğrenci tipi!");  
       }  
     }  
     public void NullSafeSet(IDbCommand cmd, object value, int index)  
     {  
       object paramVal = 0;  
       switch ((Ogrencitipi)value)  
       {  
         case Ogrencitipi.Lisans: paramVal =  
          "L"; break;  
       case Ogrencitipi.Yukseklisans: paramVal =  
          "Y"; break;  
         default:  
           throw new Exception("Geçersiz öğrenci tipi!");  
       }  
       var parameter = (IDataParameter)cmd.Parameters[index];  
       parameter.Value = paramVal;  
     }  
     public object DeepCopy(object value)  
     {  
       return value;  
     }  
     public object Replace(object original, object target, object owner)  
     {  
       return original;  
     }  
     public object Assemble(object cached, object owner)  
     {  
       return cached;  
     }  
     public object Disassemble(object value)  
     {  
       return value;  
     }  
     public SqlType[] SqlTypes  
     {  
       get { return new SqlType[] { new StringSqlType() }; }  
     }  
     public Type ReturnedType  
     {  
       get { return typeof(Ogrencitipi); }  
     }  
     public bool IsMutable  
     {  
       get { return false; }  
     }  
   }  
 }  

Mapping sınıfınızda aşağıdaki şekilde eşleştirmenizi yapabilirsiniz.

  //NHibernate 2.X  
   Map(x=>x.Ogrencitipi).CustomType<OgrencitipiMap>();  
   //NHibernate 3.X  
   Map(x=>x.Ogrencitipi).CustomTypeIs<OgrencitipiMap>();  

Yukarıdaki örnekte gördüğünüz gibi enum yapısını kullanarak istediğiniz verileri Fluent NHibernate projenizde kullanabilirsiniz. Enum kullanımının faydaları; kod okunabilirliğini arttırması, muhtemel değer kümesinin daraltılması ve tip güvenliğini sağlaması dolayısıyla hata payını en aza indirmesidir [5]. Böylelikle yeri geldiğinde projemizde enum kullanımının nasıl gerçekleşeceğini görmüş olduk.

    Umarım faydalı bir yazı olmuştur, hoşçakalın..

Kaynaklar


[1]C# ile Enum Kullanımı, http://sanalkurs.net/c-ile-enum-kullanimi-8423.html, Nisan 15, 2015.

[2]C# ve Enumeration (Enum) Kullanımı, http://emraheroglu.blogspot.com.tr/2010/01/c-ve-enumeration-enum-kullanm.html, Nisan 16, 2015.

[3]Fluent NHibernate ile kullanıcı tanımlı tipler kullanmak, http://b.zor.lu/fluent-nhibernate-ile-kullanici-tanimli-tipler-kullanmak/, Nisan 16, 2015.

[4]USING AN ENUM ON A FLUENTNHIBERNATE MAPPING [C#], http://crodrigues.com/using-a-enum-on-a-fluentnhibernate-mapping-c/, Nisan 17, 2015.

[5]Daha Okunabilir Kod ve Yaşanabilir Dünya İçin Enum’lar, http://kodcu.com/2014/08/okunabilir-kod-ve-enum/, Nisan 17, 2015.

Hiç yorum yok:

Yorum Gönder