WCF DataContract on Abstract base class and its Subclasses
I have a monitoring app that receives processing updates from other applications via WCF. Previously the apps being monitored had one "update" class to send data to the monitoring app. Now I'm writing an abstract base class that looks like this
public abstract class Update
{
public readonly DateTime TimeStamp;
public readonly int AppId;
public Update()
{
TimeStamp = DateTime.Now;
AppId = SomeMethodThatCalculatesId();
}
private int SomeMethodThatCalculatesId()
{
// my calculations ...
}
}
Here's an example subclass
public class ProcessUpdate : Update
{
public readonly string ProcessMessage;
public ProcessUpdate(string processMessage) : base()
{
if (string.IsNullOrEmpty(processMessage))
{
throw new ArgumentNullException("processMessage");
}
ProcessMessage = processMessage;
}
}
I want to be able to send the monitoring app anything derived from Update
and want to prevent Update from being instantiated, that's why it's abstract. I want one implementation for my AppId generation and for derived classes to not worry about it or alter it, that's why AppId is readonly.
Does Update
require a开发者_开发百科 DataContract
attribute tag or is that only required for my subclasses? If that's the case, can I still decorate TimeStamp
and AppId
with DataMemeber
without DataContract
and still access those properties in the monitoring app?
I think the recommendation in WFC is to communicate via interfaces. In your case that would mean making TimeStamp
and AppId
properties of the interface (decorate that with DataContract
) and decorating them with DataMember
, then you should implement this interface in Update
.
In the situation you are talking about, if you want to be able see Update
objects over WCF then you need to decorate it with DataContract
and if you want to be able to see the read only fields, then you need to decorate them with DataMember
.
You can mark the service with ServiceKnownType to tell the client about the subclasses, which should make it work when you send things derived from update.
As for marking Update as abstract on the client, not if you're using an XML based service. On the other end it doesn't see Update as abstract.
You have to mark all classes with DataContract and all members you want to transmit as DataMember. Additionally, you have to use the NetDataContract serializer, otherwise you won't be able to transmit class hierarchies or interfaces through WCF.
For an example of using NetDataContractSerializer: WCF Net Data Contract Serializer
精彩评论