Category: c#
Serialization nedir, nerede kullanılır ?
February 13th, 2008Biraz uzun bir yazı oldu ancak halen yeterli olduğunu düşünmüyorum ancak konuyu bilmeyenler için hızlı bir giriş ve önemli konuları anlatabilirim umarım.
Serialization tanımladığınız class'ları memory, disk, network gibi katmanlardan geçirmek için kullandığınız teknolojidir. .Net içinde Remoting, WebServices gibi geniş alanlarda siz farkında olmadan sessiz sedasız çalışırlar.
Tanımladığınız class serialize edilirken kullanacağınız formata göre farklı şekillerde formatterlar kullanılır. Format olarak .Net içerisinde Xml ve Binary olarak temel 2 format için formatter tanımlanmıştır.
Serialization'da temel olarak yöntem bir obje üzerinden diğer tüm obje ilişkileri çözülerek bir hedef kaynağa tüm özellikler yazılır. Karşı tarafta da aynı işlemin tersi yapılarak obje yeniden hayata geri döndürülür.
Serialization sırasında objeniz üzerindeki Method, Property gibi özellikler kaydedilmez, sadece ve sadece private olarak tanımlanmış class üzerindeki tüm yer kaplayan bilgiler (string, datetime, başka bir class) kaydedilir. Bu işlem system.reflection ile class üzerinde tüm değişkenler taranarak yapılır. Bu yüzden class'ı yeniden hayata geçirek olan tarafda o class'ın biliniyor olması gereklidir, yani client ve server tarafında aynı class'ın tanımlanmış olması (dll yada farklı yöntemlerle) gerekli.
Bu arada System.Reflection kullanıldığı ve genel bir sistem için tasarlandığından standart class yaratıp kullanmaya göre biraz daha yavaş çalışır ama korkulacak seviyede bir yavaşlıktan bahsetmiyorum.
Binary Formatter
Binary formatter çoğunlukla hız gereken yerlerde (Remoting) gibi kullanılılır. Mesela Client/Server bir uygulama yazmak istediğinizde classlarınızın çok hızlı şekilde client ve server arasında dolaşmasını istiyorsanız bu format sizin için uygun olacaktır.
Aynı şekilde bir class'ı diske kaydetmek istediğinizde .Net size itiraz etmez ancak pratikte bunun bazı yan etkileri olacaktır. Bu detaylara ilerleyen kısımda geliriz.
Xml Formatter
Bu formatda class xml formatına dönüştürülerek yapılır. Üretilen Xml formatı açık olduğu için herhangi bir başka uygulama yada platform tarafından okunabilir. Böylece web servislerinin tüm kapıları açılır.
Örnek olması için başka bir blog'dan aldığım örnek;
Code:
public class Person | |
{ | |
[XmlElement("FirstName")] | |
public string Name { get; set; } | |
public List<Pet> Pets { get; set; } | |
} | |
| |
public class Pet | |
{ | |
[XmlAttribute("Name")] | |
public string Name { get; set; } | |
[XmlAttribute("Breed")] | |
public string Type { get; set; } | |
} |
class'larını serialize etmek isteğinizde;
XML:
<PetClub xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> | |
<Members> | |
<Person> | |
<FirstName>Jon</FirstName> | |
<Pets> | |
<Pet Name="Chester" Breed="Savannah Cat" /> | |
<Pet Name="Abby" Breed="Domestic Miniature Panther" /> | |
</Pets> | |
</Person> | |
<Person> | |
<FirstName>Dan</FirstName> | |
<Pets> | |
<Pet Name="Lucy" Breed="Semi-sweet Chocolate Lab" /> | |
</Pets> | |
</Person> | |
</Members> | |
</PetClub> |
bir xml dosyası oluşacaktır. Bunu yapmak için;
Code:
public static string ConvertToXml(object item) | |
{ | |
XmlSerializer xmlser = new XmlSerializer(item.GetType()); | |
using (System.IO.MemoryStream ms = new System.IO.MemoryStream()) | |
{ | |
xmlser.Serialize(ms, item); | |
UTF8Encoding textconverter = new UTF8Encoding(); | |
return textconverter.GetString(ms.ToArray()); | |
} | |
} |
metodunu kullanabilirsiniz.
Dikkat
Serialization dikkatli kullandığınız sürece her zaman için işinize yarayacak bir araçtır. Ancak yanlış kullanımlarda başınıza ciddi sorunlar açabilir.
Diske kayıt işlemleri için ASLA binary formatter kullanmayın. Aksi halde class'larınız üzerinde değişiklik yaptığınızda yada versiyon'u numarasını değiştirdiğinizde eski verileri okuyamazsınız. (Bunu atlatmanın yolları var ancak pratikte pek işinize yaramaz)
Client/Server konuşmaları için ASLA xml formatter kullanmayın. Aksi halde ciddi performans sorunları yaşayabilirsiniz. Web servisleri içinde xml formatter kullanılsa da bu servisler zaten yavaş çalışacağı bilinerek tasarlandığından sorun olmaz ancak client server tipi uygulamalarda kabul edilen sınırı aşan bir yavaşlık yaşarsınız.
Yeterli zamanınız varsa xml için kendi mekanizmanızı oluşturun. Bu xml verisini okumak ve class'ları başlatmak için çok daha hızlıdır.
Code:
public interface IXmlSerializable | |
{ | |
void XmlParse(XmlNode node); | |
void XmlCompile(XmlWriter writer); | |
} |
şeklinde bir interface tanımlayarak kendi serialize metodlarınızı tanımlayabilirsiniz. Bu sayede reflection olmadan hızlı yollarla ve versiyon değişikliklerinden etkilenmeden yola devam edebilirsiniz.
Equals ve ==
July 3rd, 2007![]()
Kullandığınız objenin tipi ne olursa olsun .NET'de iki objenin eşit olup olmadığını karşılaştırmanın iki yolu vardır.
if ( a == b )
yada
if ( a.Equals(b) )
Görünüşte aynı işi yapıyor gibi olsalarda gerçekte oldukça farklıdırlar.
VS2005 Araçları
April 14th, 2007
Daima plugin delisi birisi olduğum için, her VS2005 (Visual Studio 2005) kurduğumda mutlaka yanında kurduğum araçlar vardır, IDE'nin kendisi güzel olsada bu tool'lar olmadan kalkansız savaşa girmiş hissederim hep.
VS2005 Team Edition
* Professional edition'dan farklı olarak içerisinde Code Analysis (yani FxCop) ve Profiling bulunur. Sadece Code Analysis için herşeye değer.
TortoiseSVN
* SVN kullanıyorsanız kullanabileceğiniz tek ve en güzel svn client'dır. Ücretsizdir.
VisualSVN
* IDE içerisinden TortoiseSVN komutlarını kullanmak için geliştirilmiş ama benim kullanım amacım sadece dosyaları rename ettiğimde svn'i haber vermesi. Ücretlidir.
NCover
* Coverage için kullandığım şahane. Ücretsizdir.
testdriven.net
* IDE içerisinden unit test rutinlerini çalıştırmak için kullanırım. NCover ile arkadaş olduğu için daha bir güzel. Ücretsizdir.
Bu araçları yanınıza aldıktan sonra "life is beatiful" şarkısını söylemeye başlayabilirsiniz.
HashTable nedir ?
September 23rd, 2006Klasik programlamanın temel taşlarından biri array tipidir. Basitçe;
int[] pi = new int[] { 3, 1, 4, 1, 5, 9 , 2, 6, 5, 4 };
şeklinde tanımlanan bir arrayde elemanlara index (elemanın numarası) değerleri ile ulaşılır. Yani;
pi[0] değeri 3'ü, p[5] değeri de 9'u taşır. Bizde gayette hızlı olan yolla index vererek array içindeki değerleri kullanabiliriz. Bunun bilgisayar mühendisliğindeki geyiği erişim O(1) dır.
Source Control Nasıl Kullanılır
July 19th, 2006Şirketimizde svn kullanıldığı için anlattıklarım onun üzerine kurulu olacak ama genel kurallar olduğu için aynısını diğer tipdeki scm'ler üzerinde de uygulayabilirsiniz.
Dizin yapısı
İlk olarak svn üzerinde aşağıdaki isimlerle iki tane ana dizin açın
/products
/projects
Eğer şirketinizde ürün geliştirmesi yapıyorsanız yaptığınız işi products altına, müşteriye özel bir uygulama ise projects dizini altına koyun. böylece ürün ile özel projeleriniz iç içe geçmez.
Bu dizinlerin altında da
/trunk
/versions
/tags
adında 3 tane dizin daha açın.
trunk dizini geliştirdiğiniz kodun en son (HEAD) halini taşıyacak. yaptığınız tüm geliştirmeleri bu dizin altında tutun.
versions altında her versiyon için trunk'ın kopyalarını tutun. yani 1999 yılında çıkardığınız versiyon 2.3 bu dizin altında bulunmalıdır. Örneğin "/versions/Turşu_2.3" gibi.
"Turşu" sizin ürününüzün adı, 2.3 ise versiyon numarasıdır.
tags altında özel olarak işaretlemek istediğiniz (yani aslında bir versiyon olmayan versiyon) kodlar bulunsun. bu dizin üstünde bir çeşit çalışma alanı üretebilirsiniz. Mesela 2.3 üzerinde bir fonksiyonu denemek istiyorsunuz ama 2.3 versiyonuna dokunmak istemiyorsunuz bu durumda bu tags altında bulunmalıdır. bu dizin altında standart bir isimlendirmeye pek ihtiyaç duymazsınız.
Çok büyük yazılım firmalarında bu tags dizini workspace olarak kullanılır ve programcılar bu dizin üstünde işini bitirdikten sonra yaptıklarını trunk dizini ile birleştirir (merge). ama bu nadir olan bir durum.
Bunları yaptığınızda elinizde şunlar olacak
* trunk dizininde kodun son hali. (yani alfa bile olmayan programcıların elinden çıkmış sürüm)
* versions dizininde işaretlenmiş versiyonlar (yani bir seviyeye gelmiş trunk'ın kopyası)
Versiyonlama
Diyelimki var olan kodunuzun üzerinden yeni bir versiyon çıkartmaya karar verdiniz bu durumda yapmanız gereken trunk dizinini versions altına numara vererek (2.3 gibi) kopyalamak.
Ve diyelimki çıkardığınız versiyon üzerinde bir hata çıktı. bunu trunk dizini altında düzeltin ve yeni bir versiyon (2.3.1 gibi) olarak kopyalayın. bu şekilde hatasız bir versiyona ulaşana kadar devam edin (2.3.5 gibi). Bu versiyon sizin production versiyonunuz olacaktır ve bu versiyonu gönül rahatlığıyla müşterinizle paylaşabilirsiniz.
Eğer farklı takımlar aynı trunk üzerinde farklı işler yapıyorlarsa düzeltmeyi trunk üzerinde değilde 2.3.1 versiyonunda yapın. daha sonrada yaptığınız düzeltmeyi trunk ile birleştirin (merge) edin. böylece çıkan kod stabil kalacaktır.
Bundan sonra belirli bir versiyonu dışarı alıp (checkout) derlemek. istediğiniz anda istediğiniz versiyona ulaşmış olacaksınız.
Derleme
Müşterinize vereceğiniz kodu asla ama asla IDE üzerinden derlemeyin. bunun için msbuild gibi commandline'dan çalışan ve otomatiğe bağladığınız bir sistem oluşturun kendinize.
Eğer derleme yapılırken size ait olmayan componentler kullanıyorsanız sadece derleme için gerekli olan dosyalarıda svn üzerinde kodların bulunduğu dizinlerin içinde "references" gibi bir dizin altında tutun. böylece o dosyalarda sizin kodunuzla birlikte versiyonlanmış olur. (korkmayın yeni versiyon çıkardığınızda sadece revizyon numarası tutulacağı için bu diskinizde yer kaplamaz)
Bunun için kendi şirketimizde bir web arabirimi oluşturduk ve istediğiniz versiyonu web üzerinden derleyebiliyorsunuz. derlenmiş exe'leride yine web server üzerinden indirebiliyorsunuz.
Son olarakda tembel programcılarınız tüm bu versiyonlama sistemini karmaşık bulacağından debug sürümdeki exe'ler için sabit bir versiyon no (0.0.0 gibi) kullanın. gerçek versiyonu release modda derlenmiş exe'ler için kullanın.
c# için bunu yapmanın yolu projedeki assemblyinfo.cs dosyasında şöyle bir değişiklik yapabilirsiniz;
#if(DEBUG)
[assembly: AssemblyVersion( "0.0.0" )]
[assembly: AssemblyFileVersion( "0.0.0" )]
#else
[assembly: AssemblyVersion( "2.3.0" )]
[assembly: AssemblyFileVersion( "2.3.0" )]
#endif
Böylece debug modda derlenen ve programcılara ait olan exe'ler her zaman 0.0.0 versiyonunda olacak tembel programcılarınızın mızmızlıklarını dinlemek zorunda kalmazsınız.
Versiyon numarasındaki son 0 hanesi için ufak bir tip olarak;
Güncel versiyonu sık olarak kullanan müşterilerimizde hergün derlenen otomatik build'ler için versiyon numarasındaki en son 0 hanesini yılın kaçıncı günü olduğuna göre ayarladık böylece, müşteriye verdiğimiz versiyonun ne güne ait olduğunu, eski mi yeni mi olduğunu anlayabiliyoruz.