在应用程序1中,我序列化和反序列化并且对象,它工作正常。但是,我希望从应用程序2中的应用程序1反序列化一个对象。我添加了将该对象定义到应用程序2的类。当我尝试反序列化它时,我收到此错误:
无法找到程序集'WindowsFormsApplication6,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null'。
如何在两个应用程序之间共享序列化对象?
答案 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);
}
}