我常常應用C#開發一些小的桌面程序,這些桌面程序每每有如下幾個特色:數據庫
由於C#程序不少狀況下都是CURD,結合上面的需求,我一直考慮作一個簡單的框架,以達到快速開發的目的。應用XML序列化(XmlSerializer)功能,我開發了一個簡單符合上面要求的底層框架。安全
我準備用XML文件做爲數據存儲,爲了保證數據同步,同時在內存中存儲一份數據,每次操做時,都是操做內存中的數據,操做完以後再同步到數據庫中。
另外,爲了保證框架的易用性,我把底層實現寫成了一個泛型類,全部操做類繼承此泛型類。併發
框架主要包括如下幾個功能:框架
數據會存儲在運行目錄下面的data目錄下,數據文件能夠由開發者指定,也能夠採用默認數據文件。dom
如何應用框架進行開發呢?我把框架打成了一個DLL文件,開發項目時,須要引用這個DLL。開發者每定義一個實體類,須要對應定義一個操做類,此操做類須要繼承個人泛型操做類。oop
注意:實體類須要有一個string類型的ID,我通常用GUID
實體類示例代碼:性能
namespace zDash { public class CodeEntity { public string Id { get; set; } public string Key { get; set; } public string Lang { get; set; } public byte[] RealContent { get; set; } } }
我把操做類寫成了單例模式,操做類示例代碼:this
namespace zDash { public class CodeBll : Wisdombud.xmldb.BaseXmlBll<CodeEntity> { private static CodeBll inst = new CodeBll(); private CodeBll() { } public static CodeBll getInst() { return inst; } } }
如何應用:spa
CodeBll.getInst().Insert(entity);
XML文件的內容線程
<?xml version="1.0"?> <ArrayOfCodeEntity xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <CodeEntity> <Id>1</Id> <Key>符號</Key> <Lang>C#</Lang> <RealContent>e1</RealContent> </CodeEntity> <CodeEntity> <Id>2</Id> <Key>符號1</Key> <Lang>C#</Lang> <RealContent>e1</RealContent> </CodeEntity> </ArrayOfCodeEntity>
由上面的例子能夠看到,應用此框架進行開發仍是很是容易的。
我會在下一篇文章裏面介紹如何應用這個框架開發一個代碼片斷管理系統
using System; using System.Collections.Generic; using System.IO; using System.Reflection; using System.Xml.Serialization; namespace Wisdombud.xmldb { public class XmlSerializerBll<T> { private static XmlSerializerBll<T> instance; private string dbFile; public string Dbfile { get { return dbFile; } set { if (!string.IsNullOrEmpty(value) && !value.Equals(dbFile)) { this.entityList.Clear(); } dbFile = value; this.ReadDb(); } } private List<T> entityList = new List<T>(); private XmlSerializerBll() { this.SetDbFile(); this.ReadDb(); } private void SetDbFile() { string folder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "data"); try { if (Directory.Exists(folder) == false) { Directory.CreateDirectory(folder); } Type type = typeof(T); if (string.IsNullOrEmpty(this.Dbfile)) { this.Dbfile = Path.Combine(folder, type.Name + ".xml"); } } catch (Exception ex) { Console.WriteLine(ex.Message); } } public static XmlSerializerBll<T> GetInstance() { if (instance == null) { instance = new XmlSerializerBll<T>(); } return instance; } public void Insert(T entity) { this.entityList.Add(entity); this.WriteDb(); } public void InsertRange(IList<T> list) { this.entityList.AddRange(list); this.WriteDb(); } public System.Collections.Generic.List<T> SelectBy(string name, Object value) { System.Collections.Generic.List<T> list = new List<T>(); if (value == null) { return list; } Type t = typeof(T); foreach (var inst in this.entityList) { foreach (PropertyInfo pro in t.GetProperties()) { if (pro.Name.ToLower() == name.ToLower()) { if (value.ToString() == (pro.GetValue(inst, null) ?? string.Empty).ToString()) { list.Add(inst); } } } } return list; } public T SelectById(string id) { Type t = typeof(T); foreach (var inst in this.entityList) { foreach (PropertyInfo pro in t.GetProperties()) { if (pro.Name.ToLower() == "id") { if (id == (pro.GetValue(inst, null) ?? string.Empty).ToString()) { return inst; } } } } return default(T); } public void UpdateById(T entity) { Type t = typeof(T); string id = string.Empty; foreach (PropertyInfo pro in t.GetProperties()) { if (pro.Name.ToLower() == "id") { id = (pro.GetValue(entity, null) ?? string.Empty).ToString(); break; } } this.DeleteById(id); this.Insert(entity); } public void DeleteById(string id) { Type t = typeof(T); T entity = default(T); foreach (var inst in this.entityList) { foreach (PropertyInfo pro in t.GetProperties()) { if (pro.Name.ToLower() == "id") { if ((pro.GetValue(inst, null) ?? string.Empty).ToString() == id) { entity = inst; goto FinishLoop; } } } } FinishLoop: this.entityList.Remove(entity); this.WriteDb(); } public List<T> SelectAll() { this.ReadDb(); return this.entityList; } public void DeleteAll() { this.entityList.Clear(); this.WriteDb(); } private void WriteDb() { XmlSerializer ks = new XmlSerializer(typeof(List<T>)); FileInfo fi = new FileInfo(this.Dbfile); var dir = fi.Directory; if (!dir.Exists) { dir.Create(); } Stream writer = new FileStream(this.Dbfile, FileMode.Create, FileAccess.ReadWrite); ks.Serialize(writer, this.entityList); writer.Close(); } private void ReadDb() { if (File.Exists(this.Dbfile)) { XmlSerializer ks = new XmlSerializer(typeof(List<T>)); Stream reader = new FileStream(this.Dbfile, FileMode.Open, FileAccess.ReadWrite); this.entityList = ks.Deserialize(reader) as List<T>; reader.Close(); } else { this.entityList = new List<T>(); } } } }
using System.Collections.Generic; namespace Wisdombud.xmldb { public class BaseXmlBll<T> where T : new() { public string DbFile { get { return this.bll.Dbfile; } set { bll.Dbfile = value; } } private XmlSerializerBll<T> bll = XmlSerializerBll<T>.GetInstance(); public void Delete(string id) { var entity = this.Select(id); bll.DeleteById(id); } public void Insert(T entity) { bll.Insert(entity); } public void Insert(List<T> list) { bll.InsertRange(list); } public System.Collections.Generic.List<T> SelectAll() { return bll.SelectAll(); } public void Update(string oldId, T entity) { bll.UpdateById(entity); } public T Select(string id) { return bll.SelectById(id); } public System.Collections.Generic.List<T> SelectBy(string name, object value) { return bll.SelectBy(name, value); } public void DeleteAll() { bll.DeleteAll(); } } }