WCF is a way to do web services in .NET since .NET Framework 3.0. The sample in this post will work with all versions of WCF.
Unit Testing
I find Unit Tests a great way to share assumptions, document usage, and learn someone's coding style. In the sample I provided a sample usage of XmlDataContractSerializer in the test named SerializeToXmlString_BasicUseCaseWorks. Yes I do not have an Assert but as a side not this unit test does test that the Serialization happens without exception.
As MSTest like most unit testing frameworks fails a test if an exception is thrown. I use MSTest because I am not doing anything that requires a particular unit testing framework. Feel free to use the one of your choice. I am not espousing its use over others.
I share with you some of my favorite places using the Contact Data Transport Object (DTO) class ContactDto. The CreateSampleData mimics a Repository method, creating a collection of some of my favorite places statically although you could imagine it hitting a data store of some type.[TestMethod]public void SerializeToXmlString_BasicUseCaseWorks(){var strategy = new XmlDataContractSerializer<ContactDto>();var data = CreateSampleData();var xml = strategy.SerializeToXmlString(data, true);}
XmlDataContractSerializer uses a base class to allow us to easily use an IOC Container to change out serializers with a config change.private ContactDto CreateSampleData(){var data = new ContactDto();data.Email = "foreachdev@gmail.com";data.FullName = "Joshua Kincaid";data.AddressCollection.AddRange(new[]{new AddressDto(){Line1="Admissions",Line2="1 Old Dominion Way",City="Norfolk",ProvinceState="Virginia",PostalCode="23529",PreferenceOrder=5},new AddressDto(){Line1="Handsome Biscuit",Line2="2511 Colonial Ave",City="Norfolk",ProvinceState="Virginia",PostalCode="23517",PreferenceOrder=1},new AddressDto(){Line1="OTTO",Line2="1 5th Ave",City="Manhattan",ProvinceState="New York",PostalCode="10003",PreferenceOrder=0}});return data;}
public class XmlDataContractSerializer<T> : XmlSerializer<T, DataContractSerializerAdapter<T>> { }
The Rest of the Code
XmlSerializer exposes the ISerializer interface for dependency injection purposes. You could have a IXmlSerializer or include a parameter for format if that is your preference.Finally, we have the simple DataContractSerializer strategy.using System;using System.IO;using System.Text;using System.Xml;namespace Jrf.Core{/// <summary>/// A Serializer component for working with POCOs that has DataContract and DataMember classes./// </summary>public class XmlSerializer<T, U> : ISerializer<T> where U : ISerializer<T>, new(){private const string _XmlDeclaration = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>";/// <summary>/// Serializes class with DataContract and DataMember attributs to Xml using an in memory stream then reads it to a string./// </summary>/// <typeparam name="T">Type to serialize.</typeparam>/// <param name="dataObject">The object to serialize.</param>/// <returns>String containing xml form of the POCO.</returns>public string SerializeToXmlString(T dataObject, bool includeDeclaration = false){var output = new StringBuilder();var stream = new MemoryStream();var reader = new StreamReader(stream);try{Serialize(dataObject, stream);if (includeDeclaration){output.Append(_XmlDeclaration);output.Append(Environment.NewLine);}output.Append(reader.ReadToEnd());}finally{//Avoids multiple dispose calls. (See FXCOP CA2202)if (reader != null){reader.Dispose();}}return output.ToString();}/// <summary>/// Serializes class with DataContract and DataMember attributs to XmlDocument using an in memory stream./// </summary>/// <typeparam name="T">Type to serialize.</typeparam>/// <param name="dataObject">The object to serialize.</param>/// <returns>XmlDocument.</returns>public XmlDocument SerializeToXmlDocument(T dataObject, bool includeDeclaration = false){var doc = new XmlDocument();using (var stream = new MemoryStream()){Serialize(dataObject, stream);doc.Load(stream);if (includeDeclaration){var root = doc.DocumentElement;var dec = doc.CreateXmlDeclaration("1.0", "UTF-8", null);doc.InsertBefore(dec, root);}}return doc;}/// <summary>/// Creates and runs the serializer./// </summary>/// <typeparam name="T">Type of Object to serialize.</typeparam>/// <param name="dataObject">Object to serialize.</param>/// <param name="stream">Stream to dump the serilization to.</param>public void Serialize(T dataObject, Stream stream){var serializer = new U();serializer.Serialize(dataObject, stream);stream.Position = 0;}}}
using System.IO;using System.Runtime.Serialization;namespace Jrf.Core{/// <summary>/// Provides Serializer Services via the DataContract Serializer./// </summary>/// <typeparam name="T"></typeparam>public class DataContractSerializerAdapter<T> : ISerializer<T>{/// <summary>/// Serializer method./// </summary>/// <typeparam name="T">Type of object to be serialized.</typeparam>/// <param name="input">Object to be serialized.</param>/// <param name="output">Xml stream.</param>public void Serialize(T input, Stream output){var serializer = new DataContractSerializer(typeof(T));serializer.WriteObject(output, input);}}}

No comments:
Post a Comment