如何解决如何动态地向Protobuf-net格式化程序添加已知类型的列表?
| 在一个项目中,我当前正在使用DataContractSerializer
序列化我的数据。而且出于性能原因,我想改用Protobuf
。
我使用序列化程序将blob存储在数据库中,并且我希望保留WCF的数据版本控制功能,以便在实际发布项目后更轻松地处理数据协定修改。
这些Blob的数据协定在编译时未知。 (在配置文件中指定了“扩展名”的列表,因此扩展名在运行时会注册“ 2”)
但是,似乎告诉protobuf已知类型的唯一方法是使用[ProtoInclude]
属性。
更具体地说,这是我要序列化的示例。
[DataContract]
public class Mydata
{
[DataMember(Order = 1)]
public int Saved
{
get;
set;
}
}
[DataContract]
public class Container
{
[DataMember(Order = 1)]
public object Data
{
get;
set;
}
}
用DataContractSerializer
,我该怎么做:
[TestMethod]
public void SerializeWithDataContractSerializer()
{
var container = new Container()
{
Data = new Mydata()
{
Saved = 1
}
};
DataContractSerializer serializer = new DataContractSerializer(typeof(Container),new[] { typeof(Mydata) });
var ms = new MemoryStream();
serializer.WriteObject(ms,container);
ms.Position = 0;
var containerSerialized = (Container)serializer.ReadObject(ms);
Assert.AreEqual(((Mydata)container.Data).Saved,((Mydata)containerSerialized.Data).Saved);
}
使用protobuf
在这里我想怎么做(但possible8ѭ不能使用knownTypes
参数):
[TestMethod]
public void SerializeWithProtoBuf()
{
var container = new Container()
{
Data = new Mydata()
{
Saved = 1
}
};
var formatter = Serializer.CreateFormatter<Container>(new[] { typeof(Mydata) });
var ms = new MemoryStream();
formatter.Serialize(ms,container);
ms.Position = 0;
var containerSerialized = (Container)formatter.Deserialize(ms);
Assert.AreEqual(((Mydata)container.Data).Saved,((Mydata)containerSerialized.Data).Saved);
}
有什么办法吗?
解决方法
由于要序列化根对象,因此在v1(已完全释放的dll)中,可以使用Serializer.NonGeneric.SerializeWithLengthPrefix和DeserializeWithLengthPrefix API进行此操作,特别是在序列化时,每个类型使用不同的字段号(标记),并使用接受类型解析器将irks-number转换回Type的反序列化重载。我目前不在电脑上,但是稍后您可以添加一个示例。
在“ v2”中,这里还有其他选项:
您可以将属性(等)标记为DynamicTypr = true,该属性存储其他类型的元数据,即使是对象属性也可以使用,但是使其与模型的联系更加紧密
您可以在运行时通过灵活的类型模型添加已知的子类型;但是通常不是来自
object
,并且我仍在探索其可能的副作用(之前已要求将其作为功能)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。