Elaborating upon the string extension methods I created for compressing and decompressing strings to and from a byte array, it turned out fairly easy to create another set of compress / decompress methods to serialize any type of object to and from a byte array containing compressed XML.
I once again took the StringZipExtensions class and added the following methods to compress any old object to a byte array:/// <summary>
/// XmlSerializes the object to a compressed byte array
/// using the specified encoding.
/// </summary>
/// <param name="objectToCompress">The object to compress.</param>
/// <param name="encoding">The encoding.</param>
/// <returns>bytes array with compressed serialized object</returns>
public static byte[] Compress(this object objectToCompress,
Encoding encoding)
{
var xmlSerializer = new XmlSerializer(objectToCompress.GetType());
using (var stringWriter = new StringWriter())
{
xmlSerializer.Serialize(stringWriter, objectToCompress);
return stringWriter.ToString().Compress(encoding);
}
}
/// <summary>
/// XmlSerializes the object to a compressed byte array using default
/// UTF8 encoding.
/// </summary>
/// <param name="objectToCompress">The object to compress.</param>
/// <returns>bytes array with compressed serialized object</returns>
public static byte[] Compress(this object objectToCompress)
{
return Compress(objectToCompress, new UTF8Encoding());
}
Here, once again, an overload using a default UTF8 encoding and a method which uses your own encoding to do the heavy lifting. Then, the methods for decompressing, which - in all modesty - are a rather neat usage of generics, I think:/// <summary>
/// Decompress an array of bytes into an object via Xml Deserialization
/// using the specified encoding
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="compressedObject">The compressed string.</param>
/// <param name="encoding">The encoding.</param>
/// <returns>Decompressed object</returns>
public static T DecompressToObject<T>(this byte[] compressedObject,
Encoding encoding)
{
var xmlSer = new XmlSerializer(typeof(T));
return (T)xmlSer.Deserialize(new StringReader(
compressedObject.DecompressToString(encoding)));
}
/// <summary>
/// Decompress an array of bytes into an object via Xml Deserialization
/// using default UTF8 encoding
/// </summary>
/// <param name="compressedObject">The compressed string.</param>
/// <returns>Decompressed object</returns>
public static T DecompressToObject<T>(this byte[] compressedObject )
{
return DecompressToObject<T>(compressedObject, new UTF8Encoding());
}
Then you can take something like this hugely complex ;-) object Personpublic class Person
{
public int Id { get; set; }
public string Name { get; set; }
public DateTime Birthday { get; set; }
public override bool Equals(object obj)
{
var toCompare = obj as Person;
if( toCompare != null )
{
return
Name.Equals(toCompare.Name) &&
Id.Equals(toCompare.Id) &&
Birthday.Equals(toCompare.Birthday);
}
return base.Equals(obj);
}
}
and serialize/compress and decompress/deserialize it like this:[Test]
public void CompressObjectTest()
{
var baseLineObject = new Person
{
Id = 99,
Name = "Tom",
Birthday = new DateTime(1969, 06, 03)
};
var compressed = baseLineObject.Compress();
var testObject = compressed.DecompressToObject<Person>();
Assert.AreEqual(testObject, baseLineObject);
}
Code downloadable here