2009-08-27 25 views
14

Ogni volta che uso WCF, cerco sempre di creare classi immutabili che finiscono sul filo (i parametri impostati nel costruttore, le proprietà sono di sola lettura). Tuttavia, questo ostacola la serializzazione WCF, che richiede che tutte le proprietà siano pubbliche get/set (che ha senso, perché deve deserializzarle)serializzazione WCC DataContract di proprietà di sola lettura?

Anche in this related post, vedo che la loro soluzione ha finito per rendere tutto Pubblico, che viola il mio senso di buona programmazione. C'è un modo per aggirare questo? Devo solo accontentarmi di questa soluzione o qualcosa come immutabilità di ghiaccioli e essere felice con esso?

L'altra cosa che ho provato è stato qualcosa di simile, in cui mi piacerebbe avere una classe base per tutto e una classe derivata che ha reso la serie inutile:

/// <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 { } 
    } 
} 

risposta

15

Se si utilizza il DataContractSerializer (che è la predefinito per WCF), è possibile serializzare anyhting che è decorata con l'attributo [DataMember] - anche una sola lettura campo:

[DataContract] 
public class VirtualMachineTemplate : VirtualMachineTemplateBase, IXmlPicklable, IEnableLogger 
{ 
    [DataMember] 
    ulong _SizeInBytes; 
} 

Ma è necessario utilizzare il DataContractSerializer - non il serializzatore XML. Il serializzatore XML può serializzare SOLO le proprietà pubbliche (e lo farà, a meno che non si inserisca un [XmlIgnore] su di esse).

Il DataContractSerializer è diverso:

  • non ha bisogno di un costruttore di default dei parametri-less
  • lo farà solo serializzare quello che si contrassegna esplicitamente [DataMember]
  • ma che può essere qualsiasi cosa - un campo, una proprietà e qualsiasi visibilità (privata, protetta, pubblica)
  • è leggermente più veloce di XmlSerializer, ma non si ottiene molto controllo sulla forma dell'XML - si ottiene solo una voce in ciò che è incluso

Vai a questa blog post e questo blog post per pochi ulteriori suggerimenti e trucchi.

Marc

+12

No, è ancora necessario includere il set o fallisce. – Craig

+0

È possibile impostare SerializeReadOnlyTypes su true in DataContractSerializerSettings. –

+0

Aw, i link del post del blog sono morti ora :( –

3

per garantire sia l'immutabilità e la facilità di implementazione, allo stesso tempo aggiungere un setter per la proprietà privata di servire deserializzazione. Succede molto sotto il cofano, ma funziona.

Problemi correlati