Whenever I use WCF, I always try to make immutable classes that end up going over the wire (i.e. parameters set in constructor, properties are read-only). However, this gets in the way of WCF serialization, which demands that all properties be Public get/set (which makes sense, because it has to deserialize them)
Even in this related post, I see that their solution ended up making everything Public, which violates my sense of good programming. Is there any way around this? Do I have to just settle for this solution or something like popsicle immutability and be happy with it?
The other thing I tried was something like this, where I'd have a base class for everything and a derived class that made the set useless:
/// <summary>
/// This represents a discovered virtual-machine template that can be
/// instantiated into a RunningVirtualMachine
/// </summary>
[DataContract]
[XmlRoot("VMTemplate")]
public class VirtualMachineTemplateBase
{
[DataMember]
public virtual ulong SizeInBytes { get; set; }
}
/// <summary>
/// This class is the real guts of VirtualMachineTemplate that we're hiding
/// from the base class.
/// </summary>
[XmlInclude(typeof(VirtualMachineTemplateBase))]
public class VirtualMachineTemplate : VirtualMachineTemplateBase, IXmlPicklable, IEnableLogger
{
ulong _SizeInBytes;
public override ulong SizeInBytes {
get { return _SizeInBytes; }
set { }
}
}
DataContractSerializer(Type, IEnumerable<Type>) Initializes a new instance of the DataContractSerializer class to serialize or deserialize an object of the specified type, and a collection of known types that may be present in the object graph.
No, the DataContractAttribute is not required - WCF will infer serialization rules.
A data contract is a formal agreement between a service and a client that abstractly describes the data to be exchanged. That is, to communicate, the client and the service do not have to share the same types, only the same data contracts.
The process forms a sequence of bytes into a logical object; this is called an encoding process. At runtime when WCF receives the logical message, it transforms them back into corresponding . Net objects. This process is called serialization.
If you use the DataContractSerializer (which is the default for WCF), you can serialize anyhting that's decorated with the [DataMember]
attribute - even a read-only field:
[DataContract]
public class VirtualMachineTemplate : VirtualMachineTemplateBase, IXmlPicklable, IEnableLogger
{
[DataMember]
ulong _SizeInBytes;
}
But you need to use the DataContractSerializer - not the XML serializer. The XML serializer can ONLY serialize public properties (and it will, unless you put a [XmlIgnore] on them).
The DataContractSerializer is different:
[DataMember]
See this blog post and this blog post for a few more tips and tricks.
Marc
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With