在域类和同一目标类的多个版本之间来回转换时,可以使用哪种策略



对于我的特定上下文,我控制目标类。它们是基于XSD自动生成的,并且有巨大的重叠,因为它们代表同一类的不同版本。每个版本都是一个超过5000行的巨大C#类。

无法删除对旧版本的支持。这意味着我们总是需要能够将域类映射到几个不同的版本,然后再映射回来。从一个版本到另一个版本,总是会有一些微小但破坏性的更改。90%以上的目标类始终是相同的,即使每个版本的代码都是重复的。

目前,每种格式都有一个大的映射,这太可怕了。太多了。重复。密码此外,开发人员倾向于在需要的地方进行更新,并跳过其他所有内容,这意味着各个版本经常不同步,这意味著一个版本将被更新以做其他版本没有的事情。这也不理想。

所以我想问你的是:你能用什么策略来进行这种映射?

考虑到类的大小,并且必须维护多个版本,我建议序列化和序列化。假设它们在其他方面彼此近似,JsonConvertJsonConvert.Deserialize<TargetClass>(JsonConvert.Serialize(sourceClass))应该可以解决这个问题,尽管我还没有与这么大的模型合作过,对它的性能有任何想法

或者,您可以使用t4模板(如果您不在.net Core中(,使用反射到通用方法或其他方法来生成映射。

就防止开发者问题而言。。。接口,基类,它们尽可能集中地定义这些内容。代码审查,以确保开发人员尽可能对最底层进行更改。

我敢肯定,你可以用静态的using语句做一些棘手的事情。

像这样愚蠢的东西

using OldVersion = path.to.the.class.CantRenameThis;
class CantRenameThis : OldVersion

我们最终找到了一个实现主要目标的解决方案:

  • 体面的编译时安全性,以发现映射错误
  • 重复代码消除
  • 不会干扰自动生成的代码

我们通过利用自动生成的类作为分部生成来实现这一点。这意味着我们可以扩展它们。

我们最终创建了如下的接口/类层次结构:

  • ClassV1实现IClassVerySpecificV1
  • ClassV2实现IClassVerySpecificV2
  • IClassVerySpecificV1实现SpecificA、SpecificB、SpecificC和IClassBasic
  • IClassVerySpecificV1实现SpecificB、SpecificC、SpecificD和IClassBasic

然后映射器将看起来像:

  • ClassV1Mapper需要SpecificAMapper、SpecificBMapper、SpecificCMapper和ClassBasicMapper
  • ClassV2Mapper需要SpecificBMapper、SpecificCMapper、SpecificDMapper和ClassBasicMapper

通过这种方式,我们可以通过将属于IClassBasic的所有内容都放入ClassBasicMapper来映射90%的所有内容。

然而,我们确实遇到了一些问题:

  • 正如你已经猜到的,我们最终得到了很多接口。比你想要的更多
  • 有时一个字段存在于多个版本之间,但具有不同的(枚举(值。我们的域模型将具有超集,该超集具有指定哪些值对哪些版本有效的属性

相关内容

最新更新