What I want to do is serialize a reference to a well-known global object, something like the ones derived from System.Type. I don't want the object to be serialized, I just want to transfer it's name to the other side where I'd use the name to find the global instance the reference should point to.
The secret is in using the IObjectReference interface. It can be used to have an object say "this is not me: there I am over there". The interface is used in object deserialization: if a deserializer retrieves an object that implements IObjectReference, it will call the object's GetRealObject method to get a reference the real object. So what we do is this: we add to our "global" object's class a string property called nameUsedForSerialization. It will be used only for serialization purposes (you may have already guessed it). We implement IXmlSerializable so that when the object is serialized, we'll serialize only its name. When it's deserialized, an empty object will be created that contains just the name. And then, when GetRealObject() is called, this name will be used to find the real object. Like this:
#region IXmlSerializable Members
private string nameUsedForSerialization;
public void WriteXml(System.Xml.XmlWriter writer)
{
string name = this.GetType().ToString() + "." + SomeInstanceName;
writer.WriteString(name);
}
public System.Xml.Schema.XmlSchema GetSchema()
{
return null;
}
public void ReadXml(System.Xml.XmlReader reader)
{
nameUsedForSerialization = reader.ReadString();
}
#endregion
#region IObjectReference Members
public object GetRealObject(StreamingContext context)
{
return MyUtilityClass.FindRealObject(nameUsedForSerialization);
}
#endregion