Serializer 类 |
命名空间: XPatchLib
public class Serializer : IDisposable
Serializer 类型公开以下成员。
名称 | 说明 | |
---|---|---|
Serializer |
初始化 Serializer 类的新实例。
|
名称 | 说明 | |
---|---|---|
Combine(ITextReader, Object) |
反序列化指定 ITextReader 包含的增量文档,并与 原始对象 进行数据合并。
| |
Combine(ITextReader, Object, Boolean) |
以可指定是否覆盖原始对象的方式反序列化指定 ITextReader 包含的增量文档,并与 原始对象 进行数据合并。
| |
Dispose | Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. | |
Divide | ||
RegisterType |
向 Serializer 注册类型与主键集合。
|
比较同一对象类型的两个的实例间的差异内容,并产生增量的内容,使用指定的 文档写入器 ITextWriter 实例将增量内容写入文档, 也可以将增量的文档通过制定的文档读取器 ITextReader 实例反序列化并附加至原始的对象实例上。
使用 Divide 方法将原始对象与更新后对象之间差异内容的的公共字段和读/写属性转换为 增量数据。它不转换方法、索引器、私有字段或只读属性。
使用 Combine 方法将读取增量内容,并将增量数据与待合并的原始对象的数据合并,产生新的对象实例。(也可以使用重载方法,直接在原始对象上附加数据,这样将不会产生新的对象实例)
简单对象增量序列化/反序列化示例
using System; using System.Text; using XPatchLib; using System.IO; namespace XPatchLib.Example { public class SimpleExample { public static void Main(string[] args) { Book OriBook = new Book() { ISBN = "0-385-50420-9", Name = "The Da Vinci Code", Author = new Author() {FirstName = "Dan", LastName = "Brown"} }; Book RevBook = new Book() { ISBN = "0-385-50420-9", Name = "达芬奇密码", Author = new Author() {FirstName = "丹", LastName = "布朗"} }; StringBuilder context = new StringBuilder(); System.Xml.XmlWriterSettings settings = new System.Xml.XmlWriterSettings(); settings.Encoding = new UTF8Encoding(false); settings.OmitXmlDeclaration = true; settings.ConformanceLevel = System.Xml.ConformanceLevel.Document; Serializer serializer = new Serializer(typeof(Book)); using (StringWriter strWriter = new StringWriter(context)) { using (XmlTextWriter writer = new XmlTextWriter(strWriter)) { serializer.Divide(writer, OriBook, RevBook); } } Book NewBook = null; using (XmlTextReader reader = new XmlTextReader(new StringReader(context.ToString()))) { NewBook = serializer.Combine(reader, OriBook, false) as Book; } Console.WriteLine(NewBook); } } [XPatchLib.PrimaryKey("ISBN")] public class Book { static string OUTPUT; static Book() { StringBuilder output = new StringBuilder(); output.AppendLine("ISBN:{0}"); output.AppendLine("Name:{1}"); output.AppendLine("Author:{2} {3}"); OUTPUT = output.ToString(); } public string ISBN { get; set; } public string Name { get; set; } public Author Author { get; set; } public override string ToString() { return string.Format(OUTPUT, this.ISBN, this.Name, this.Author.FirstName, this.Author.LastName); } } public class Author { public string FirstName { get; set; } public string LastName { get; set; } } }
序列化增量内容如下所示:
<Book> <Author> <FirstName>丹</FirstName> <LastName>布朗</LastName> </Author> <Name>达芬奇密码</Name> </Book>
输出内容如下:
ISBN:0-385-50420-9 Name:达芬奇密码 Author:丹 布朗
较复杂的对象增量序列化示例
using System; using System.IO; using System.Text; using System.Xml; namespace XPatchLib.Example { public class ComplexObjCombineAndDivide { public static void Main() { var t = new ComplexObjCombineAndDivide(); t.Divide("patch.xml"); t.Combine("patch.xml"); } private void Divide(string filename) { //原始对象 var order = CreatePuchaseOrder(); //更新后的对象 var newOrder = CreatePuchaseOrder(); //改变更新后对象的内容 //由于直接修改了主键的内容,将被视为删除了原有主键为Widget S的对象,并新增了主键为Widget B的对象。 newOrder.OrderedItems[0].ItemName = "Widget B"; newOrder.OrderedItems[0].Description = "Big widget"; newOrder.OrderedItems[0].UnitPrice = (decimal) 26.78; newOrder.OrderedItems[0].Quantity = 5; newOrder.ShipCost = (decimal) 12.51; //产生增量内容 var serializer = new Serializer(typeof(PurchaseOrder)); using (var writer = new XmlTextWriter(filename, new UTF8Encoding(false))) { serializer.Divide(writer, order, newOrder); } } private void OuputPuchaseOrder(PurchaseOrder order) { Console.WriteLine("OrderDate: " + order.OrderDate); ReadAddress(order.ShipTo, "Ship To:"); Console.WriteLine("Items to be shipped:"); foreach (var oi in order.OrderedItems) Console.WriteLine("\t" + oi.ItemName + "\t" + oi.Description + "\t" + oi.UnitPrice + "\t" + oi.Quantity + "\t" + oi.LineTotal); Console.WriteLine(); Console.WriteLine("Subtotal:\t" + order.SubTotal); Console.WriteLine("Shipping:\t" + order.ShipCost); Console.WriteLine("Total:\t" + order.TotalCost); } private void Combine(string filename) { //合并增量内容至原始对象 var serializer = new Serializer(typeof(PurchaseOrder)); var oldOrder = CreatePuchaseOrder(); PurchaseOrder newOrder = null; using (var fs = new FileStream(filename, FileMode.Open)) { using (var reader = new XmlTextReader(fs)) { newOrder = (PurchaseOrder) serializer.Combine(reader, oldOrder); } } Console.WriteLine("OldOrder: "); OuputPuchaseOrder(oldOrder); Console.WriteLine("---------- "); Console.WriteLine("NewOrder: "); OuputPuchaseOrder(newOrder); } private void ReadAddress(Address a, string label) { Console.WriteLine(label); Console.WriteLine("\t" + a.Name); Console.WriteLine("\t" + a.Line1); Console.WriteLine("\t" + a.City); Console.WriteLine("\t" + a.State); Console.WriteLine("\t" + a.Zip); Console.WriteLine(); } private PurchaseOrder CreatePuchaseOrder() { var result = new PurchaseOrder(); var billAddress = new Address(); billAddress.Name = "Teresa Atkinson"; billAddress.Line1 = "1 Main St."; billAddress.City = "AnyTown"; billAddress.State = "WA"; billAddress.Zip = "00000"; result.ShipTo = billAddress; result.OrderDate = DateTime.Now.ToLongDateString(); var i1 = new OrderedItem(); i1.ItemName = "Widget S"; i1.Description = "Small widget"; i1.UnitPrice = (decimal) 5.23; i1.Quantity = 3; OrderedItem[] items = {i1}; result.OrderedItems = items; result.ShipCost = (decimal) 12.51; return result; } public class Address { public string City; public string Line1; public string Name; public string State; public string Zip; } [XPatchLib.PrimaryKey("ItemName")] public class OrderedItem { public string Description { get; set; } public string ItemName { get; set; } public decimal LineTotal { get { return UnitPrice * Quantity; } } public int Quantity { get; set; } public decimal UnitPrice { get; set; } } public class PurchaseOrder { public OrderedItem[] OrderedItems; public string OrderDate { get; set; } public decimal ShipCost { get; set; } public Address ShipTo { get; set; } public decimal SubTotal { get { var subTotal = new decimal(); foreach (var oi in OrderedItems) subTotal += oi.LineTotal; return subTotal; } } public decimal TotalCost { get { return SubTotal + ShipCost; } } } } }
序列化增量内容的 输出如下所示:
<?xml version="1.0" encoding="utf-8"?> <PurchaseOrder> <OrderedItems> <OrderedItem Action="Remove" ItemName="Widget S" /> <OrderedItem Action="Add"> <Description>Big widget</Description> <ItemName>Widget B</ItemName> <Quantity>5</Quantity> <UnitPrice>26.78</UnitPrice> </OrderedItem> </OrderedItems> </PurchaseOrder>
输出内容如下:
OldOrder: OrderDate: 2017年3月12日 Ship To: Teresa Atkinson 1 Main St. AnyTown WA 00000 Items to be shipped: Widget S Small widget 5.23 3 15.69 Subtotal: 15.69 Shipping: 12.51 Total: 28.20 ---------- NewOrder: OrderDate: 2017年3月12日 Ship To: Teresa Atkinson 1 Main St. AnyTown WA 00000 Items to be shipped: Widget B Big widget 26.78 5 133.90 Subtotal: 133.90 Shipping: 12.51 Total: 146.41