我尝试序列化一个由Craft或Reagent组成的树:
[ProtoContract]
[ProtoInclude(1, typeof(Craft))]
[ProtoInclude(2, typeof(Reagent))]
public interface IReagent : IEquatable
{
[ProtoMember(1)]
int ItemId { get; set; }
[ProtoMember(2)]
int Quantity { get; set; }
}
[ProtoContract]
public class Reagent : IReagent
{
[ProtoMember(1)]
public int ItemId { get; set; }
[ProtoMember(2)]
public int Quantity { get; set; }
}
[ProtoContract]
public class Craft : IReagent
{
[ProtoMember(1)]
public int Skill { get; set; }
[ProtoMember(2)]
public Profession Profession { get; set; }
[ProtoMember(3)]
public List<IReagent> Reagents { get; set; }
[ProtoMember(4)]
public int ItemId { get; set; }
[ProtoMember(5)]
public int Quantity { get; set; }
}
序列化代码:
[ProtoMember(2)]
public Profession Profession { get; set; }
[ProtoMember(3)]
public List<IReagent> Reagents { get; set; }
[ProtoMember(4)]
public int ItemId { get; set; }
[ProtoMember(5)]
public int Quantity { get; set; }
测试代码:
public class ProtobufMessageSerializer<T> : ISerializer<T> {
private readonly ILog logger;
public ProtobufMessageSerializer(ILog logger)
{
this.logger = logger;
}
public byte[] Serialize(T entity)
{
byte[] message = new byte[0];
try
{
using (var ms = new MemoryStream())
{
Serializer.Serialize(ms, entity);
message = ms.ToByteArray();
}
logger.Info(string.Format("Serialized message with a length of: {0}", message.GetHumanReadableSize()));
}
catch (Exception ex)
{
logger.Warn(ex);
}
return message;
}
public T Deserialize(byte[] message)
{
T result = default(T);
try
{
using (var ms = new MemoryStream(message))
{
result = Serializer.Deserialize<T>(ms);
}
}
catch (Exception ex)
{
logger.Warn(ex);
}
return result;
}
}
序列化后,我得到:
[Test]
public void TestSerializer()
{
var responseSerializer = container.Resolve<ISerializer<IReagent>>();
var repos = container.Resolve<CraftRepository>();
var craft = repos.GetAll().First();
var serializedForm = responseSerializer.Serialize(craft);
var deserializedForm = responseSerializer.Deserialize(serializedForm);
Assert.NotNull(deserializedForm);
}
堆栈跟踪:
The type cannot be changed once a serializer has been generated for Bargains.Data.Craft (Bargains.Data.IReagent)
答案 0 :(得分:2)
基本上,界面支持目前只扩展到成员;我应该以这种方式使用serialzie / deserialize是错误的,或者让它工作! (后者显然更可取)。
如果你引入一个包装器,如:
[ProtoContract]
public class Wrapper {
[ProtoMember(1)]
public IReagent Reagent {get;set;}
}
并序列化 ,然后它应该工作。您还需要修复以下损坏的合同:
[ProtoContract]
[ProtoInclude(1, typeof(Craft))]
[ProtoInclude(2, typeof(Reagent))]
public interface IReagent
{
[ProtoMember(3)] // <==== was 1
int ItemId { get; set; }
[ProtoMember(4)] // <==== was 2
int Quantity { get; set; }
}
(这些数字不能在单一类型中重复)