序列化为XML - 私有属性

时间:2009-08-28 13:49:14

标签: .net xml-serialization poco

我正在寻找一种方法来序列化包含一些只读属性的POCO。在某些Google和StackOverflow搜索中,我看到了以下建议:

  • 使用 DataContractSerializer ;或
  • 使用 SoapFormatter BinaryFormatter ;或
  • 读/写属性;
  • 替换我的只读属性

我的课很简单,看起来像:

public class MyClass
{
    public int Id { get; private set; }
    public string Name { get; private set; }
    public MyClass(int id, string name)
    {
        Id = id;
        Name = name;
    }
}

所以,

  • 我不想让我的属性读/写。如果它们是只读的,那是因为我的域模型要求只读属性。域模型不能因此而改变。
  • 我不想使用DataContractSerializer,因为这会污染我的域模型与序列化相关的东西。
  • BinaryFormatter不是一个很好的选择,因为结果是byte[],我想将其视为string(我不想处理Encondings反序列化我的对象时也一样。)

我真正想要的是能够序列化只读属性的 XmlSerializer类

您知道任何此类实施吗?还是其他任何方便的解决方案?

谢谢!

2 个答案:

答案 0 :(得分:4)

好吧,通常XmlSerializer无法序列化只读属性...但是有可能使用内部集序列化属性:您需要生成XML序列化程序集,并将其声明为“朋友“使用InternalsVisibleTo属性进行汇编。您可以通过将以下代码添加到项目文件来自动执行此操作:

  <Target Name="AfterBuild"
          DependsOnTargets="AssignTargetPaths;Compile;ResolveKeySource"
          Inputs="$(MSBuildAllProjects);@(IntermediateAssembly)"
          Outputs="$(OutputPath)$(_SGenDllName)">
    <SGen BuildAssemblyName="$(TargetFileName)"
          BuildAssemblyPath="$(OutputPath)"
          References="@(ReferencePath)"
          ShouldGenerateSerializer="true"
          UseProxyTypes="false"
          KeyContainer="$(KeyContainerName)"
          KeyFile="$(KeyOriginatorFile)"
          DelaySign="$(DelaySign)"
          ToolPath="$(SGenToolPath)">
      <Output TaskParameter="SerializationAssembly"
              ItemName="SerializationAssembly" />
    </SGen>
  </Target>

在AssemblyInfo.cs中:

[assembly: InternalsVisibleTo("MyAssembly.XmlSerializers")]

当然,您可能不希望属性具有内部集,但如果这样做,上述解决方案应该有效。

答案 1 :(得分:1)

虽然如果序列化可以访问私人财产会很遗憾,但截至今天,这并不容易。

但是架构解决方案还有另一种选择。 不要破坏您的业务领域要求,而是将您的图层分开,类似于nTeir设计并实施DTO ......

如果您将业务,datafacade / dataadaptor(工厂模式非常适合)和DataAccess层分成3个项目,您可以通过引用该业务从不了解您的DTO来控制。 Hense如果您决定删除或实现序列化或将其交换为保存到SQL服务器,则不会影响业务层中的任何内容。

总有一个垮台,还有更多的代码要编写: *你必须为你希望进入Dataaccess的每个实体编写一个对象转换器 *你可能会破坏一些OO隐藏sinse a。业务中的保存方法需要在Dataface中转换为正确的类型,然后再转向dataaccess

你可以用nHybinate或类似的东西使这更容易。 干杯 巧克力