class - 如何设计一个版本转换器(Json.net),在没有太多代码污点的情况下将非常旧的版本处理为新版本

标签 class serialization architecture versioning json.net

我的要求是创建一个高效的版本转换器设计。让我们假设每个版本中都演化了以下类。

//版本1

    internal class PatientV1
    {
        public string FullName { get; set; }
        public string PatientNr { get; set; }
        public GenderV1 Gender { get; set; }
    }

    internal enum GenderV1
    {
        MALE,
        FEMALE
    }

//版本2

    internal class PatientV2
    {
        public Name FullName { get; set; }
        public string PatientNr { get; set; }
        public GenderV2 Gender { get; set; }
    }

    internal class Name
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Title { get; set; }
    }

    internal enum GenderV2
    {
        MALE,
        FEMALE,
        UNKNOWN
    }

//版本3

    internal class PatientV3
    {
        public IPerson Person { get; set; }
        public string PatientNr { get; set; }
    }

    internal interface IPerson
    {
        Name Name { get; set; }
        GenderV3 Gender { get; set; }
    }


    internal class Person : IPerson
    {
        public Name Name { get; set; }
        public GenderV3 Gender { get; set; }
    }


    internal enum GenderV3
    {
        MALE,
        FEMALE,
        MALE_TO_FEMALE_CONVERSION_INPROGRESS,
        FEMALE_TO_CONVERSION_INPROGRESS,
        UNKNOWN
    }

我创建了 JsonConverter 将一个版本反序列化为另一个版本。这增加了许多转换器的组合((n-1)!),例如。

  1. PatientV1ToV2Converter,用于从版本 1 转换为版本 2
  2. PatientV1ToV3Converter,用于从版本 1 转换为版本 3
  3. PatientV2ToV3Converter,用于从版本 2 转换为版本 3

因此,我希望 PatientV1ToV3Converter 调用 PatientV1ToV2Converter 将患者从 PatientV1 带到 PatientV2,然后 PatientV1ToV3Converter 对 PatientV2 进行处理,使其成为 PatientV3。

我希望在应用程序目录中不存在任何旧版本的 Patient(PatientV1 和 PatientV2)的情况下完成所有这些操作。

任何设计,无论有或没有旧的 dll 限制,都适合我。

最佳答案

我在我的项目中做了类似的事情

我已经设置

serializerSettings.Converters = new List<JsonConverter>() { new MyAppVersionConverter() };

在这个MyAppVersionConverter中,我重写了ReadJson并编写了以下代码

JObject jObjectV = JObject.Load( reader );
//Get the type information from JObject by getting the "$type" property and strip it to get the version
string objectVersion = GetVersion(jObjectV.GetValue("$type"));

现在,通过添加或删除属性来修改现有的jObjectV,以转换为所需的版本,然后

例如从我的代码

JProperty firstNameProp = new JProperty( "FirstName", firstName );
JProperty lastNameProp = new JProperty( "LastName", lastName );
JProperty typeProperty = new JProperty( "$type", "MyDetailV2.EmployeeDetail, MyDetailV2, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null" );

JObject jObjectV2 = new JObject();
jObjectV2.Add( typeProperty );
jObjectV2.Add( firstNameProp );
jObjectV2.Add( lastNameProp );

return jObjectV2.ToObject<EmployeeDetail>();

我还在完善东西。一旦我完成了完整的更改,我就会发布。

如果您在这方面有任何问题,请告诉我

关于class - 如何设计一个版本转换器(Json.net),在没有太多代码污点的情况下将非常旧的版本处理为新版本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13413831/

相关文章:

c++ - 将二进制数据写入 private ofstream 会产生意想不到的结果

Python继承模式——如何处理反序列化

java - 序列化二叉搜索树

n 层应用程序中的 WCF 服务层 : performance considerations

assembly - 是否可以在 x64 操作系统上运行 x86 程序集?

html - 全局 CSS 辅助类是个好主意吗?

java存储实例变量并使用键值之一进行访问

c++ - 派生类是否可以具有不在 C++ 中的基类中的构造函数?

c++ - 为什么在一个类中可以使用多个std vector ?

web-services - ServiceStack 跨平台互操作性