Generic Yapılarda Serialization ile Kaydetme ve Yükleme
Selamlar,
Bugün farklı sınıflar için sürekli aynı kodları tekrar etmek yerine, generic bir yapıda belli bir nesnenin, nasıl serialize edip kaydedilebileceğini ve deserialize edilip yüklenebileceğini inceleyeceğiz.
Bugün yazacağımız kodlar, benim de gündelik hayatta bolca kullandığım kodların küçük bir parçasıdır.
Şimdi gelin isterseniz üzerinde çalışacağımız sınıfımızı oluşturalım. Aşağıda görüldüğü gibi bu bir başvuru class’ıdır.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
public class Application { const string FileSavePath = @"c:\data\Application.xml"; public Guid ID { get; set; } public string City { get; set; } public int Rank { get; set; } public bool Active { get; set; } public List<string> GeneralList { get; set; } public Application() { ID = Guid.NewGuid(); GeneralList= new List<string>(); } } |
İlk sistemde ilgili başvuruyu “Xml” olarak kaydetmek için aşağıdaki gibi sınıf tipi olan “Application” tanımlanıp bu sınıfa göre “XmlSerialization” işlemi yapılmaktadır.
1 2 3 4 5 6 7 8 9 |
public void BasicSave() { var xs = new XmlSerializer(typeof(Application)); using (TextWriter sw = new StreamWriter(FileSavePath)) { xs.Serialize(sw, this); } } |
Yine aynı şekilde ilk sisteme göre yukarıda belirtilen yol ile kaydedilen “Application” sınıfı, “Deserialize” edilerek, Xml formatından Class‘a çevrilmiş ve ilgili sınıfın propertyleri aşağıdaki gibi doldurulmuştur.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
public void BasicLoad() { var xs = new XmlSerializer(typeof(Application)); using (var sr = new StreamReader(FileSavePath)) { var tempData = (Application)xs.Deserialize(sr); ID = tempData.ID; City = tempData.City; Rank = tempData.Rank; Active = tempData.Active; GeneralList = tempData.GeneralList; } } |
Şimdi gelin ilgili Application sınıfını, Console bir uygulamanın “Main()” methodunda aşağıdaki gibi kaydedelim. Kaydedilme işleminden sonra “Application.xml“‘in örnek Xml çıktısı yukarıdaki gibidir.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
class Program { static void Main(string[] args) { Application app = new Application(); app.Active = true; app.City = "Istanbul"; app.GeneralList.Add("Makale yaz"); app.GeneralList.Add("Musluğu tamir et"); app.GeneralList.Add("Güncellemeleri yap"); app.Rank = 5; app.BasicSave(); Console.Write("Application Kaydedildi."); Console.ReadLine(); } } |
Yazılan “Application.xml” dosyasının basit şekilde “Deserialize” edilip, Application class’ına çevrilerek okunması aşağıdaki gibidir. Örnek ekran çıktısı yukarıdaki gibidir.
1 2 3 4 5 6 7 8 9 10 11 |
Application app = new Application(); app.BasicLoad(); Console.WriteLine("Şehir: "+app.City); Console.WriteLine("ID: "+app.ID); Console.WriteLine("Sıra: "+app.Rank); Console.WriteLine("İşler:"); foreach(string job in app.GeneralList) { Console.WriteLine("."+job); } Console.ReadLine(); |
Generic Save: Aşağıdaki örnekde sabit bir type belirtilmeden, generic tipde bir nesnenin nasıl “Serialize” edilip kaydedildiği gösterilmektedir. Kaydedilen örnek “.xml” uzantılı dosya yukarıdaki gibidir. Burada amaç farklı tipte nesneler içini kod tekrarı yapmamak ve tüm object türleri için aynı kodu kullanmaktır.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
class Program { static void Main(string[] args) { Application app = new Application(); app.Active = true; app.City = "Istanbul"; app.GeneralList.Add("Makaleyi yayına al."); app.GeneralList.Add("Arabaya benzin koy."); app.GeneralList.Add("Motoru yıka."); app.Rank = 5; app.BasicSave(); string fileName = @"c:\data\Application2.xml"; Save<Application>(fileName, app); Console.Write("Generic Application Kaydedildi."); Console.ReadLine(); } public static bool Save<T>(string FileName, Object Obj) { var xs = new XmlSerializer(typeof(T)); using (TextWriter sw = new StreamWriter(FileName)) { xs.Serialize(sw, Obj); } if (File.Exists(FileName)) return true; else return false; } } |
Generic Load: Aşağıdaki örnekte generic tipde bir nesne “Deserialize” edilip okunmaktadır. Kısaca kod tekrarından kurtulmak için, tipden bağımsız bir yükleme methodu yazılmıştır.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
public static T Load<T>(string FileName) { Object rslt; if (File.Exists(FileName)) { var xs = new XmlSerializer(typeof(T)); using (var sr = new StreamReader(FileName)) { rslt = (T)xs.Deserialize(sr); } return (T)rslt; } else { return default(T); } } |
İlgili “Load()” methodunun kullanım şekli aşağıdaki gibidir. Örnek ekran çıktısı yukarıdaki gibidir.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
static void Main(string[] args) { string fileName = @"c:\data\Application2.xml"; var fileData = Load<Application>(fileName); Console.WriteLine("Şehir: " + fileData.City); Console.WriteLine("ID: " + fileData.ID); Console.WriteLine("Sıra: " + fileData.Rank); Console.WriteLine("İşler:"); foreach (string job in fileData.GeneralList) { Console.WriteLine("." + job); } Console.ReadLine(); } |
İsterseniz şimdi gelin bu Generic Save kodları daha şık bir hale getirelim: Aşağıda görüldüğü gibi ilgili “Save()” methodu artık “<T>” şeklinde bir tip beklememekte ve gelen nesenin tipi “GetType()” methodu ile alınmaktadır. Böylece daha kısa ve daha anlaşılır bir kod elde edilmiş olunup gereksiz yere “Save()” methodu çağrılırken tip tanımlaması yapılmamıştır.
1 2 3 4 5 6 7 8 9 10 11 12 |
public static bool SaveBetter(string FileName, Object Obj) { var xs = new XmlSerializer(Obj.GetType()); using (TextWriter sw = new StreamWriter(FileName)) { xs.Serialize(sw, Obj); } if (File.Exists(FileName)) return true; else return false; } |
Aşağıda yeni “SaveBetter()” methodunun kullanım şekli ve yukarıda ekran çıktısı gözükmektedir. Görüldüğü gibi Application sınıfına ait herhangi bir tanımlama yapılmamıştır.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
static void Main(string[] args) { Application app = new Application(); app.Active = true; app.City = "Seattle"; app.GeneralList.Add("Daha güzel kod yaz."); app.GeneralList.Add("Publish yapmayı unutma."); app.GeneralList.Add("Yemek söyle."); app.Rank = 5; string fileName = @"c:\data\Application3.xml"; SaveBetter(fileName, app); var fileData = Load<Application>(fileName); Console.WriteLine("Şehir: " + fileData.City); Console.WriteLine("ID: " + fileData.ID); Console.WriteLine("Sıra: " + fileData.Rank); Console.WriteLine("İşler:"); foreach (string job in fileData.GeneralList) { Console.WriteLine("." + job); } Console.ReadLine(); } |
Böylece Generic yapılarda Serializa ve Desrializa işlemler yaparak, belirlenen bir nesneyi kaydettik ve tekrar yükleyip özelliklerini ekrana bastık. Daha sonra ilgili kodları, tipden bağımsız tüm nesler için kullanılabilecek temiz sade bir hale getirdik.
Geldik bir makalenin daha sonuna. Yeni bir makalede görüşmek üzere hoşçakalın.
Source Code : https://github.com/borakasmer/GenericSerializer
Kaynak : https://www.codeproject.com/Articles/1105754/Generic-Csharp-NET-Object-Save-Load
Son Yorumlar