protobuf-net 隐式合约 [英] protobuf-net implicit contracts

查看:38
本文介绍了protobuf-net 隐式合约的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有人有一个工作示例,可以将 protobuf-net 用作 BinaryFormatter 的替代品?这可能吗?

Does anyone have a working example where protobuf-net can be used as a drop-in replacement for BinaryFormatter? Is that even possible?

实际上我只需要一个类似于

Actually I just need a serializer for one message type which looks like

public class A {
  public B[] Bs { get;set; }
  public C[] Cs { get;set; }
}

所有类型都定义在不同的程序集中并具有很多属性.是否有一个选项可以自动生成包含所有公共属性的原型合同,用于类 A 和其他使用的类型(B、C),所以像

All types are defined in a different assembly and have a lot of properties. Is there an option to automatically generate proto contracts with all public properties included, for class A and other used types (B, C), so something like

var formatter = ProtoBuf.Serializer.CreateFormatter<A>()

有效吗?

推荐答案

首先,protobuf-net 并不打算也不声称是 BinaryFormatter 的 100% 替代品.它的功能略有不同.

Firstly, protobuf-net is not intended to be, and does not claim to be, a 100% drop in replacement for BinaryFormatter. It has slightly different features.

你愿意做一点反思吗?基本上,支持ImplicitFields,但目前只能通过[ProtoContract] 实现,不能通过RuntimeTypeModel 方便地完成,即有点痛苦,在我的名单上.不过,我应该指出,我认为隐式字段有点冒险,只有在您知道 DTO 内部结构不会改变时才应该这样做!但是:要回答您的问题,您可以迭代您期望的类型,并手动将它们添加到模型中:

Would you be content to do a little reflection? Basically, there is support for ImplicitFields, but currently this is only available via [ProtoContract], and cannot be done conveniently via RuntimeTypeModel, which is a bit of a pain, and is on my list. Although, I should point out that I consider implicit-fields to be a bit risky, and it should only be done if you know the DTO innards won't change! But: to answer your question, you could iterate over the types you expect, and add them to the model manually:

static void Main()
{
    Prepare(typeof(A), typeof(B), typeof(C));
    // if you really want to use IFormatter...
    var formatter = RuntimeTypeModel.Default.CreateFormatter(typeof (A));
    var obj = new A {Bs = new B[] {new B()}};
    using (var ms = new MemoryStream())
    {
        formatter.Serialize(ms, obj);
        ms.Position = 0;
        var clone = formatter.Deserialize(ms);
    }
}
static void Prepare(params Type[] types)
{
    if(types != null) foreach(var type in types) Prepare(type);
}
static void Prepare(Type type)
{
    if(type != null && !RuntimeTypeModel.Default.IsDefined(type))
    {
        Debug.WriteLine("Preparing: " + type.FullName);
        // note this has no defined sort, so invent one
        var props = type.GetProperties(); 
        Array.Sort(props, (x, y) => string.Compare(
            x.Name, y.Name, StringComparison.Ordinal));
        var meta = RuntimeTypeModel.Default.Add(type, false);
        int fieldNum = 1;
        for(int i = 0 ; i < props.Length ; i++)
        {
            meta.Add(fieldNum++, props[i].Name);
        }

    }
}

注意这里完全没有必要使用IFormatter;你也可以使用 RuntimeTypeModel.Default.Serialize(...)Serializer.Serialize(...).

Note that the use of IFormatter here is entirely unnecessary; you could also use RuntimeTypeModel.Default.Serialize(...) or Serializer.Serialize<T>(...).

作为脚注:我会建议定义模型更多......可重复.例如:

As a footnote: I would advise defining the models more ... repeatably. For example:

RuntimeTypeModel.Default.Add(typeof(A)).Add("Bs", "Cs");
RuntimeTypeModel.Default.Add(typeof(B)).Add("Foo");
RuntimeTypeModel.Default.Add(typeof(C)).Add("Bar", "Blap", "Blop");

这篇关于protobuf-net 隐式合约的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆