在应用程序之间共享序列化对象

时间:2013-05-08 09:35:09

标签: c# serialization deserialization

在应用程序1中,我序列化和反序列化并且对象,它工作正常。但是,我希望从应用程序2中的应用程序1反序列化一个对象。我添加了将该对象定义到应用程序2的类。当我尝试反序列化它时,我收到此错误:

  

无法找到程序集'WindowsFormsApplication6,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null'。

如何在两个应用程序之间共享序列化对象?

3 个答案:

答案 0 :(得分:7)

将可序列化对象的定义放入单独的程序集中,然后将共享程序集的引用添加到每个项目中。 (格式化程序在第一个项目中添加对程序集的引用 - 它们实际上必须引用同一个类,而不仅仅是类的相同副本)

答案 1 :(得分:6)

如果您使用BinaryFormatter,则在数据中包含完整类型名称,其中包括DTO所在的程序集(类型始终由其程序集定义)。这里的一个选择是创建一个单独的DTO库,您可以从每个库中引用 - 但请注意BinaryFormatter在版本控制方面仍然非常不可靠:我看到人们丢失了数据,因为他们编辑了他们的DTO并且一切都停止了工作。

我强烈建议使用非类型相关的序列化器;例如,XmlSerializer / DataContractSerializer / JSON.NET / ServiceStack的JsonSerializer或protobuf-net。所有这些都可行,但重要的是不会以两种不同的方式打击你

  • 他们非常版本化
  • 他们不关心你是否在程序集之间移动类型

即使 with 这样,为序列化类型维护单独的DTO程序集可能最方便,但它不会强制你。最终,由于这些序列化器都很乐意跨越OS /跨版本/跨语言/跨CPU工作,“不同组件”这一事实本身就是一个“meh,无论如何”。

关键点:BinaryFormatter可能很脆弱。除了飞行中的数据之外,我从不推荐它(例如,在两个AppDomain个实例之间进行远程处理)。我当然不会将它用于任何持续一段时间的事情,因为我无法保证我将来能够重新加载它。

答案 2 :(得分:0)

这是我目前的工作方式

    public sealed class VersionDeserializer : SerializationBinder
    {
        public override Type BindToType(string assemblyName, string typeName)
        {
            var assemVer1 = Assembly.GetExecutingAssembly().FullName;
            var deserializeType = Type.GetType(string.Format("{0}, {1}", typeName, assemVer1));

            return deserializeType;
        }
    }

    private object FromByteArray(byte[] data)
    {
        var bf = new BinaryFormatter
        {
            Binder = new VersionDeserializer()
        };

        using (MemoryStream ms = new MemoryStream(data))
        {
            return bf.Deserialize(ms);
        }
    }