【问题标题】:Protobuf-net extensions? Can I Serialize special objects in a different way?Protobuf-net 扩展?我可以用不同的方式序列化特殊对象吗?
【发布时间】:2013-11-15 16:40:14
【问题描述】:

我是堆栈溢出的新手,如果已经提出这个问题,我深表歉意;我到处找,我什么也找不到。最相关的主题是这个

Is there an extensibility mechanism in protobuf-net to control raw de/serialization?

问题是,我正在使用 protobuf-net 序列化方法,我想在序列化/反序列化过程中以不同的方式处理一些对象(出于多种原因的特殊对象)。

例如,假设我有一个名为 Connection 的类,它连接到数据库。

[ProtoContract]
public class Connection
{
    [ProtoMember(1)]
    public SqlConnection myConnection {get; set}

    public Connection(String connectionString)
    {
       this.myConnection = new SqlConnection(connectionString);
    }           
}

当我尝试正常进行时,我想使用 protobuf-net 序列化这个类:

public void Serialize(Object instance, string path)
{
    using (var stream = new FileStream(path, FileMode.Create))
    {
        Serializer.Serialize(stream, instance);
    }
}

public void someMethod()
{
    Connection p = new Connection("user id=username;" +
    "password=password;server=serverurl;" +
    "Trusted_Connection=yes;" +
    "database=database; " +
    "connection timeout=30");

    Serialize(p);       
}

我得到一个异常(这不是问题所在)...假设我想以不同的方式对待这个对象(SqlConnection)。假设我想序列化它的 connectionString 而不是对象本身,所以当我反序列化它时,我可以再次连接到相应的数据库......

我知道我可以做一些事情,比如拥有另一个类(它实际上将被序列化的那个),它包含有关特殊对象(在本例中为 connectionString)的相应信息。但这不是我要找的。

这只是一个例子,我可以有更复杂的对象,我想以不同的方式处理。

因此,我的问题是:有没有办法可以实现这一目标?我阅读了有关扩展的信息,但我不太了解它们。

提前致谢。

【问题讨论】:

    标签: protobuf-net


    【解决方案1】:

    目前,这样做的方法是通过“代理”。基本上,您可以创建如下类型:

    [ProtoContract]
    public class SqlConnectionDto
    {
        [ProtoMember(1)]
        public string Server { get; set; }
        [ProtoMember(2)]
        public string Database { get; set; }
        // ...
    
        public static explicit operator SqlConnection(SqlConnectionDto dto)
        {
            if (dto == null) return null;
            var builder = new SqlConnectionStringBuilder
            { 
                DataSource = dto.Server,
                InitialCatalog = dto.Database,
                //...
            };
            return new SqlConnection(builder.ConnectionString);
        }
        public static explicit operator SqlConnectionDto(SqlConnection conn)
        {
            if (conn == null) return null;
            return new SqlConnectionDto
            {
                Server = conn.DataSource,
                Database = conn.Database,
                //...
            };
        }
    }
    

    并告诉引擎使用它:

    RuntimeTypeModel.Default.Add(typeof(SqlConnection), false)
        .SetSurrogate(typeof(SqlConnectionDto));
    

    但是,它目前提供对序列化程序的完全控制。扩展值确实是一种选择,但如果没有您尝试序列化的具体示例,很难评论这是否合适。

    【讨论】:

    • 非常感谢,我运行了示例,一切正常。我认为这对于我正在进行的项目来说已经足够了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多