TL;DR;有没有一个库或协议允许我序列化.NET应用程序中的一些数据,并在WP、Win8、iOS和Android上进行反序列化,同时保留对象之间的引用,就像它们在代码中一样,即如果单个实例X是Y和Z的成员,当Y和Z被反序列化时,应该只有一个X对象。
详细版本:
我希望能够序列化A和B类型的一些对象,其中A有一个B类型的成员,B的一个实例可以是A的许多实例的成员。我应该能够在WP、Win8、iOS和Android上进行反序列化,并且在反序列化数据时应该保持相同的关系。遗憾的是,我现在无法在Android和iOS上进行测试。
序列化机制的要求
- 反序列化时保留对象引用
- 序列化的开销其实并不重要,因为设备会像三个月一次那样获得新数据
- 虽然开销并不重要,但对同一对象的引用不要再序列化一次是很重要的,因为这可能会导致非常大的序列化数据
- 能够使用.NET进行序列化。不需要在其他平台上进行序列化
- 能够在WP、Win8、iOS、Android上进行反序列化
[DataContract(IsReference = true)]
public class A
{
[DataMember]
public string Name { get; set; }
[DataMember]
public B MemberB { get; set; }
}
[DataContract(IsReference = true)]
public class B
{
[DataMember]
public string Name { get; set; }
}
Example object graph:
var b1 = new B { Name = "B1" };
var aa = new List { new A { MemberB = b1, Name = "A1" }, new A { MemberB = b1, Name = "A2" } };
我尝试过使用DataContract序列化并将IsReference=true添加到DataContract属性中。这在桌面.NET和WP之间很有魅力,我认为它会在Windows 8上运行,但如果不编写自己的反序列化程序,我甚至找不到在iOS和Android上反序列化DataContractSerialization的方法,更不用说对保留引用的开箱即用支持了。如果有一个库可以在iOS和Android上提供反序列化,而不需要额外的努力,那么DataContract序列化对我来说将是完美的。
我还试用了OData服务。OData有适用于iOS和Android的客户端库,但它能按预期工作。似乎如果实体上有PK,则引用将被保留。我在WP和.NET控制台应用程序上测试了如下:
DemoService service = new DemoService(new Uri("http://services.odata.org/OData/OData.svc/"));
var productsQuery = (DataServiceQuery<Product>)
(from p in service.Products.Expand("Category")
where p.Category.ID == 1
select p);
productsQuery.BeginExecute(
(result) =>
{
var actualProducts = productsQuery.EndExecute(result).ToList();
System.Diagnostics.Debug.WriteLine(actualProducts[2].Category == actualProducts[4].Category); //outputs true because both categories are the same
},
null);
它似乎有效,但我的测试做得对吗?它在iOS和Android客户端上这样有效吗?我想避开OData,因为它对我的案子来说太重了。
我意识到我可以给每个对象一个ID,只使用这些ID来建模对象图,但我希望有一个更干净的解决方案。我还希望避免编写自己的序列化代码。
子问题:
- 有没有一种方法可以在iOS和Android上反序列化DataContract序列化,而无需编写自己的反序列化程序
- iOS和Android的OData客户端是否保留对象引用?他们容易相处吗
- iOS版Mono和Android版Mono在保留对象引用的同时支持DataContract反序列化吗
谢谢你抽出时间。
我会使用谷歌的协议缓冲区。其他语言还有其他实现,包括Objective C和C#。
更新:
如果我在做这件事,我会从在任何地方使用.NET开始,包括在Android上(通过使用MonoDroid)和(在iOS上使用MonoTouch)。是的,您现在可以在任何平台上共享C#代码!
我希望序列化的每个对象都有一个等价的对象,定义为Protocol Buffer对象。每个对象都有一个序列化的哈希值作为其ID。对象中的每个引用都将被定义为一个哈希值。
然后,在每个对象中都有一些代码来遍历下面的对象,并在执行过程中序列化到协议缓冲区对象。填充哈希值引用。
每个对象引用都会被查找并存储在对象的字典(哈希值/地址)中(如果不存在的话)。这也是序列化的。这将停止序列化对象两次,因为在整个操作中对象只序列化/取消序列化一次。这是通过设置/清除字典中对象的地址来完成的。
我以前写过这些东西,没什么大不了的。