How do you find out when you've been loaded via XML Serialization?
.net, c#, serialization, xml-serialization
Solution
Hmmm... it's still not pretty but you could refactor your deserialization logic into a dedicated class which could notify the deserialized object that it originated from XML before returning it to the caller.
Update: I think this should be fairly easy to do without straying too far from the patterns laid by the framework... you'd just need to ensure that you use the CustomXmlSerializer. Classes that need this notification just need to implement IXmlDeserializationCallback
using System.Xml.Serialization;
namespace Custom.Xml.Serialization
{
public interface IXmlDeserializationCallback
{
void OnXmlDeserialization(object sender);
}
public class CustomXmlSerializer : XmlSerializer
{
protected override object Deserialize(XmlSerializationReader reader)
{
var result = base.Deserialize(reader);
var deserializedCallback = result as IXmlDeserializationCallback;
if (deserializedCallback != null)
{
deserializedCallback.OnXmlDeserialization(this);
}
return result;
}
}
}
Problem
I'm trying to load a tree of objects via XML serialisation, and at the moment it will load the objects in, and create the tree quite happily. My issue revolves around the fact that these classes support a level of auditing. What I'd like to be able to do is call some method on each object after it has finished being loaded. For the sake of argument, assume I have a fairly generic object tree with differing classes at different levels, like: ``` <Customer name="Foo Bar Inc."> <Office IsHq="True"> <Street>123 Any Street</Street> <Town name="Anytown"> <State name="Anystate"> <Country name="My Country" /> </State> </Town> </Office> <Office IsHq="False"> <Street>456 High Street</Street> <Town name="Anycity"> <State name="Anystate"> <Country name="My Country" /> </State> </Town> </Office> </Customer> ``` Is there any way using the default serialisers (In the similar way that you can create methods like `ShouldSerializeFoo`) to determine when loading has finished for each object? Edit: I should point out that the obvious case of exposing something akin to an `OnLoaded()` method that I could call after deserialising, strikes me as being a "bad thing to do". Edit2: For the sake of discussion this is my current hack "approach", which works for the basic level, but the child City node still thinks it needs to be saved with changes (in the real world the object model is a lot more complex, but this will at least compile, without the need for full source) ``` public class Office { [XmlAttribute("IsHq")] public bool IsHeadquarters { get; set; } [XmlElement] public string Street { get; set; } [XmlElement] public Town Town { get; set; } protected virtual void OnLoaded() {} public static OfficeCollection Search() { OfficeCollection retval = new OfficeCollection(); string xmlString = @" <Office IsHq='True'> <Street>123 Any Street</Street> <Town name='Anytown'> <State name='Anystate'> <Country name='My Country' /> </State> </Town> </Office>"; XmlSerializer xs = new XmlSerializer(retval.GetType()); XmlReader xr = new XmlTextReader(xmlString); retval = (OfficeCollection)xs.Deserialize(xr); foreach (Office thisOffice in retval) { thisOffice.OnLoaded(); } return retval; } } ```