移动类时保持 .NET 序列化数据的兼容性 [英] Maintain .NET Serialized data compatability when moving classes

查看:16
本文介绍了移动类时保持 .NET 序列化数据的兼容性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有已序列化的数据.与序列化数据相关联的类是一个大型遗留项目的一部分,该项目具有许多第三方引用,这组核心数据不需要这些引用.现在我需要将这些数据读入另一个应用程序.我想将数据类重构为一个单独的项目,该项目可以在 2 个应用程序之间共享,因此我最终不需要所有 3rd 方库.我还想保持与以前保存的数据的兼容性.我不需要更改类中的任何字段,只需更改它们所在的项目即可.

I have data that's been serialized. The classes associated with the serialized data is part of a large legacy project which has a number of 3rd party references which are not needed for this core set of data. Now I have a need to read this data into another application. I'd like to refactor out the data classes into a separate project which can be shared between the 2 application so I don't end up needing all the 3rd party libraries. I also want to maintain compatibility with data that's been previously saved. I don't need to change any fields in the classes, just the project where they are located.

到目前为止,我已经将课程转移到了一个新项目中.我将命名空间与旧项目中的命名空间保持一致.但是,这还不足以读取对象.我收到一个 SerializationException,指出解析错误,没有与 Xml 密钥 a1 MyCorp.MyApp.DatabaseRoot MyCorp.MyApp 关联的类型".查看 SOAP 生成的 XML,引用的模式已更改.例如,我有一个类 MyCorp.Dashboard.DatabaseRoot 最初在项目 DashboardLibrary 中.这已移至项目 DashboardData(但仍使用名称空间 MyCorp.Dashboard.DatabaseRoot).XML 以这种方式更改:

So far, I've moved the classes to a new project. I've kept the namespaces the same as they were in the old project. But, this hasn't been sufficient to read the objects. I get a SerializationException stating "Parse Error, no type associated with Xml key a1 MyCorp.MyApp.DatabaseRoot MyCorp.MyApp". Looking at the SOAP generated XML, the schemas referenced have changed. For example, I have a class MyCorp.Dashboard.DatabaseRoot originally in project DashboardLibrary. This was moved to project DashboardData (but still using namespace MyCorp.Dashboard.DatabaseRoot). The XML changed in this way:

Orig: <a1:DatabaseRoot id="ref-1" xmlns:a1="http://schemas.microsoft.com/clr/nsassem/MyCorp.Dashboard/MyCorp.Dashboard">
New:  <a1:DatabaseRoot id="ref-1" xmlns:a1="http://schemas.microsoft.com/clr/nsassem/MyCorp.Dashboard/DashboardData">

所以,我的问题是

  • 是否可以移动类并保持兼容性?我似乎快要成功了.
  • 如果是这样,我如何控制最后一位架构信息(MyCorp.Dashboard 与 DashboardData).原始似乎基于目录位置,而第二个是项目名称.我曾尝试更改新项目中的目录结构,但没有成功.还有什么我遗漏的吗?

谢谢.

推荐答案

您需要实现自定义 SerializationBinder.覆盖 BindToType 方法根据名称选择要加载的类型:

You need to implement a custom SerializationBinder. Override the BindToType method to select the type to load based on its name:

public override Type BindToType(string assemblyName, string typeName)
{
    if (assemblyName == "MyOldAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null")
    {
        if (typeName == "MyOldNamespace.MyOldClass")
        {
            return typeof(MyNewClass);
        }
    }
    // Fall back to the default behavior, which will throw
    // a SerializationException if the old assembly can't be found
    return null;
}

(这是一个非常基本的实现,在实际场景中,您可能会使用更好的映射逻辑).

(this is a very basic implementation, in a real-world scenario you would probably use a better mapping logic).

您还可以覆盖 BindToName 如果您需要重新序列化数据以便旧程序集仍然可以读取它.这允许您自定义序列化对象的程序集和类型名称.

You can also override BindToName if you need to reserialize the data so that it can still be read by the old assembly. This allows you to customize the assembly and type name of the serialized object.

拥有自定义SerializationBinder 后,只需将其分配给Binder 格式化程序的属性,并从那里正常使用它.

Once you have your custom SerializationBinder, you just need to assign it to the Binder property of the formatter, and use it normally from there.

如果您需要更改类型的结构(添加或重命名字段、更改类型...),您将需要实现一个 ISerializationSurrogate 将旧数据映射到新类型结构.

If you need to change the structure of the types (add or rename fields, change types...), you will need to implement a ISerializationSurrogate to map the old data to the new type structure.

这篇关于移动类时保持 .NET 序列化数据的兼容性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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