XML Serialization - Private Properties

I am looking for a way to serialize POCO that contains some read-only properties. In some Google searches and StackOverflow, I saw the following suggestions:

  • use DataContractSerializer ; or
  • use SoapFormatter or BinaryFormatter ; or
  • replace my readonly properties with read / write properties ;

My classes are very simple, they look like this:

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; } } 

So,

  • I do not want my properties to read / write. If they are read-only, this is because my domain model is requesting read-only properties. Because of this, the domain model cannot change.
  • I do not want to use the DataContractSerializer , as this will pollute my domain model with serialization-related materials.
  • BinaryFormatter not a very good option, as the result is byte[] , and I would like to treat it as a string (and I don't want to deal with Encondings the same way when Deserializing my object).

I would really like the XmlSerializer class , which can serialize read-only properties .

Do you know about such an implementation? Or any other convenient solution?

Thanks!

+4
source share
2 answers

Well, usually an XmlSerializer cannot serialize read-only properties ... however, it is possible to serialize properties with an internal set: you need to generate an XML serialization assembly and declare it as a β€œfriend” using the InternalsVisibleTo attribute. You can automate this by adding the following code to the project file:

  <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> 

And in AssemblyInfo.cs:

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

Of course, you may not want the properties to have an internal set, but if you do, the solution above should work.

+4
source

Although it would be nice if you serialized access to private property, unfortunately, today there is no easy way.

But there is another solution to the architecture. DO NOT destroy business domain requirements; instead, separate your layers similar to the nTeir project and implement the DTO ...

If you separate your activities, then the Datafacade / dataadaptor (factory template works well here) and the DataAccess levels in 3 projects that you can control, referring to the fact that the business never knows about your DTOs. If you decided to remove or implement serialization or exchange it for saving to the SQL server, you would not affect anything in your business level.

There is always one fall, there is even more code to write: * you need to write a converter object for both objects for which you want to go to Dataaccess * you potentially destroy the part of OO that hides sinse. The Save method in business must be converted to the correct type in the Dataface before moving on to dataaccess

You can make it a lot easier with something like nHybinate or similar. cheers choco

+1
source

All Articles