ImmutableXmlSerializer

CSharp · Console

/Program.cs

using System;
using System.IO;
using System.Text;
using System.Xml.Serialization;
					
public class Program
{
	public static void Main()
	{
		var serializer = new ModelXmlSerializer();
		
		var xml = "<Model><Element attr1=\"Hello World\">5</Element></Model>";

		var model = serializer.Deserialize(xml);

		Console.WriteLine($"model.Element.Value = {model.Element.Value}; model.Element.Attr1 = \"{model.Element.Attr1}\"");

		var newXml = serializer.Serialize(model);

		Console.WriteLine($"newXml = \"{newXml}\"");
	}
}

public class ModelXmlSerializer : ImmutableXmlSerializer<ImmutableModel, Model>
{
	protected override ImmutableModel ConvertToImmutable(Model mutable)
	{
		return new ImmutableModel(mutable);
	}
	
	protected override Model ConvertToMutable(ImmutableModel immutable)
	{
		return new Model(immutable);
	}
}

public abstract class ImmutableXmlSerializer<TImmutable, TMutable>
{
	private readonly MyXmlSerializer<TMutable> _xmlSerializer;

	public ImmutableXmlSerializer()
	{
		_xmlSerializer = new MyXmlSerializer<TMutable>();
	}

	public TImmutable Deserialize(string xml)
	{
		return ConvertToImmutable(_xmlSerializer.Deserialize(xml));
	}

	public string Serialize(TImmutable obj)
	{
		return _xmlSerializer.Serialize(ConvertToMutable(obj));
	}
	
	protected abstract TImmutable ConvertToImmutable(TMutable mutable);
	protected abstract TMutable ConvertToMutable(TImmutable immutable);
}

public class MyXmlSerializer<T>
{
	private readonly XmlSerializer _xmlSerializer;

	public MyXmlSerializer()
	{
		_xmlSerializer = new XmlSerializer(typeof(T));
	}

	public T Deserialize(string xml)
	{
		using (TextReader reader = new StringReader(xml))
		{
			return (T)_xmlSerializer.Deserialize(reader);
		}
	}

	public string Serialize(T obj)
	{
		var builder = new StringBuilder();
		using (TextWriter writer = new StringWriter(builder))
		{
			_xmlSerializer.Serialize(writer, obj);
		}
		
		return builder.ToString();
	}
}

public class ImmutableModel
{
	public ImmutableModel(Model model)
	{
		this.Element = new ImmutableElement(model.Element);
	}
	
	public ImmutableElement Element { get; private set; }
}

public class ImmutableElement
{
	public ImmutableElement(Element element)
	{
		this.Value = element.Value;
		this.Attr1 = element.Attr1;
	}
	
    public int Value { get; private set; }

    public string Attr1 { get; private set; }
}

[XmlRoot("Model")]
public class Model
{	
	public Model()
	{
	}
	
	public Model(ImmutableModel model)
	{
		this.Element = new Element(model.Element);
	}
	
	[XmlElement("Element")]
	public Element Element { get; set; }
}

public class Element
{
	public Element()
	{
	}
	
	public Element(ImmutableElement element)
	{
		this.Value = element.Value;
		this.Attr1 = element.Attr1;
	}
	
    [XmlText]
    public int Value { get; set; }

    [XmlAttribute("attr1")]
    public string Attr1 { get; set; }
}
;