2009-08-27 9 views
14

Zawsze, gdy używam WCF, zawsze staram się tworzyć niezmienne klasy, które kończą się przechodzeniem przez przewód (tj. Parametry ustawione w konstruktorze, właściwości są tylko do odczytu). Jednak staje się to przeszkodą w serializacji WCF, która wymaga, aby wszystkie właściwości były publicznymi get/set (co ma sens, ponieważ musi deserializować je)Serializacja WCF DataContract właściwości tylko do odczytu?

Nawet w this related post widzę, że ich rozwiązanie spowodowało, że wszystko Publiczne, co narusza moje poczucie dobrego programowania. Czy jest jakiś sposób obejścia tego? Czy muszę po prostu zadowolić się tym rozwiązaniem lub czymś w rodzaju niezmienności popsicle i być z tego zadowolonym?

Inną rzeczą próbowałem było coś takiego, gdzie musiałbym klasy bazowej za wszystko i klasę pochodną że wykonany zestaw bezużyteczne

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

Odpowiedz

15

Jeśli używasz DataContractSerializer (co jest

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

Ale trzeba użyć DataContractSerializer - nie jest serializatora XML: nawet pole tylko do odczytu - domyślna dla WCF), można szeregować anyhting że urządzone z atrybutem [DataMember]. Serializator XML może TYLKO serializować właściwości publiczne (i będzie, chyba że umieścisz na nich [XmlIgnore]).

DataContractSerializer jest inna:

  • nie trzeba konstruktora domyślnego parametru mniej
  • to będzie tylko serialize co wyraźnie oznaczyć z [DataMember]
  • ale to może być cokolwiek - pole, właściwość i każda widoczność (prywatna, chroniona, publiczna)
  • jest nieco szybsza niż XmlSerializer, ale nie masz dużej kontroli nad kształtem XML - możesz tylko powiedzieć, co obejmuje:

Zobacz te blog post i ten blog post, aby uzyskać więcej wskazówek i porad.

Marc

+12

Nie, musisz jeszcze dołączyć zestaw lub nie. – Craig

+0

Można ustawić właściwość SerializeReadOnlyTypes na wartość true w menu DataContractSerializerSettings. –

+0

Aw, linki do postów na blogu są już martwe :( –

3

Aby zapewnić zarówno niezmienność i łatwą implementację jednocześnie dodać prywatną setter dla właściwości służyć deserializacji. Wiele dzieje się pod maską, ale działa.

Powiązane problemy