2009-08-27 44 views
14

Bất cứ khi nào tôi sử dụng WCF, tôi luôn cố gắng tạo các lớp không thay đổi sẽ kết thúc dây dẫn (tức là các tham số được đặt trong hàm tạo, các thuộc tính là chỉ đọc). Tuy nhiên, điều này được trong cách serialization WCF, mà đòi hỏi rằng tất cả các tài sản được công nhận/thiết lập (mà có ý nghĩa, bởi vì nó phải deserialize chúng)WCF DataContract serialization thuộc tính chỉ đọc?

Ngay cả trong this related post, tôi thấy rằng giải pháp của họ đã kết thúc Công khai, vi phạm ý thức lập trình tốt của tôi. Có cách nào để khắc phục điều này? Tôi có phải chỉ giải quyết cho giải pháp này hoặc một cái gì đó như bất biến popsicle và được hạnh phúc với nó?

Một điều khác tôi đã cố gắng là một cái gì đó như thế này, nơi tôi muốn có một lớp cơ sở cho tất cả mọi thứ và một lớp có nguồn gốc khiến tập vô ích:

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

Trả lời

15

Nếu bạn sử dụng DataContractSerializer (đó là mặc định cho WCF), bạn có thể serialize anyhting đó là trang trí với các thuộc tính [DataMember] - thậm chí là một trường chỉ đọc:

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

Nhưng bạn cần phải sử dụng DataContractSerializer - không phải là serializer XML. Bộ nối tiếp XML chỉ có thể tuần tự hóa các thuộc tính công khai (và nó sẽ, trừ khi bạn đặt một [XmlIgnore] vào chúng).

Các DataContractSerializer là khác nhau:

  • nó không cần một constructor mặc định tham số-less
  • nó sẽ chỉ serialize những gì bạn một cách rõ ràng đánh dấu với [DataMember]
  • nhưng đó có thể là bất cứ điều gì - một trường, thuộc tính và bất kỳ chế độ hiển thị nào (riêng tư, được bảo vệ, công khai)
  • nhanh hơn một chút so với XmlSerializer, nhưng bạn không có nhiều quyền kiểm soát hình dạng của XML - bạn chỉ nhận được lời nói trong những gì được bao gồm

Xem này blog postblog post này để biết thêm một số mẹo và thủ thuật.

Marc

+12

Không, bạn vẫn cần bao gồm bộ hoặc không thành công. – Craig

+0

Bạn có thể đặt SerializeReadOnlyTypes thành true trong DataContractSerializerSettings. –

+0

Ôi, các liên kết bài đăng trên blog đã chết ngay bây giờ: ( –

3

Để đảm bảo cả tính bất biến và thực hiện dễ dàng đồng thời thêm một setter tin cho các tài sản để phục vụ deserialization. Rất nhiều xảy ra dưới nắp ca-pô, nhưng nó hoạt động.

Các vấn đề liên quan