Why do we need to decorate serialisation attributes to classes and properties or implement some interface for persisting the data?

StackOverflow https://stackoverflow.com/questions/13458854

문제

As far as my understanding goes most of the serialization/de-serialization technique uses reflection to create object and set or get values. So why do one explicitly bind these attribute such as [XmlIgnore]... for xml, [Serializable]... in Binary serialisation, [JsonPropery]... Json.Net etc in the class. Since these are like cross cutting concerns as a far as an object concerned, cant we do the same outside the object?

If the concerns are separated the user can have control over which portion of the object graph/tree one needs to serialize/de- serialize under which context and how etc?

Is there any such framework that makes the entire serialization as aspect, i.e. outside the concern of the classes?

Edit1: My requirements are as follows My application stores the data in a huge tree structure. The customer requirement is to be able to serialize certain data in xml format, and certain portion of the data in Json (I do not know why such requirement) and we have most of the data serialized in binary as a legacy code.

Now that there are classes in which a portion of the data needs to be shown in XML format and another portion (these can be part of the xml data or binary serialization data as well) in Json.

So I am looking for a solution in which

  1. Classes should not be aware of any serialization specific attributes, instead the serializer framework can give enough tools to easily do serialization without touching the class.
  2. The framework should allow persisting both private and public data which I wanted. This can be specific to a class or instance or specific to some properties of an instance in some context.
    E.g.
    • SaveTemplate: Should save only few nodes from each branch of the tree
    • SaveDocument: Should save one branch from the tree completely
    • SavePackage: Should save entire tree.
  3. Should allow serialize into different format, such as xml, binary, json etc for different purposes.

So I am planning to evaluate certain Serialization framework to achieve the same. I found Json.Net which can give me the following

  • No serialization tag to be put for public properties just like xml serialization.
  • Backward compatibility to Binary Serialization. i.e. I do not have to change the binary serialization interface implementation
  • Does not need a parameter less constructor.

However I still need the capability mentioned in point 2) and 3) above. I have not yet explored Json.Net in detail or any other framework.

Does any framework can help me achieve the same?

도움이 되었습니까?

해결책

With your edit, referring to private fields among other things: frankly you're stretching the feature-set of what any one serializer will offer. You can probably use extension APIs to do some of it, but it'll be a lot of work, and not 100%. You will spend a lot if time fighting the serializers and debugging.

In such cases, there is a much better solution: write a set of DTO types completely unrelated to your domain entities. Serialize/deserialize the DTOs - feel free go annotate the DTOs like there is no tomorrow: their single purpose is to express serialization intent. Then just map to/from the DTO and entity types.

This way, you get the best if both worlds. The serializers are happy with the DTOs (and you can shape the data as you want, by tweaking the DTO types), and your domain entities are squeaky clean, completely unaware of serialization concerns.

다른 팁

Well, yes. XML serialization can work on any object with the following two caveats, neither of which require attribute decoration:

  • The object must have a public, parameterless constructor.
  • All information that should be serialized must be in a publicly-visible field or property.

Easy. However, XML serialization without attributes produces the "default" XML structure for the object. If you're trying to make the XML class produced by serializing your object conform to a pre-existing XML document format, like a SOAP request, or HTML or XAML, this default structure probably won't work, and so it must be customized by using either attributes, telling the built-in serializer engine how to tweak what it produces, or a custom serialization routine that basically overrides the built-in engine and does exactly what you want.

Binary serialization, at its most basic, requires one single attribute, Serializable, to be applied to the class itself. This is little more than a hint to the compiler or runtime that this class's definition should be included in a set of "serialization assemblies" that are created for that purpose. However, again, if you just tell it the object can be serialized, and don't tell it how, you get the default behavior; fields may be included that you don't want, or the serializer may run into trouble with something it can't serialize.

In short, there are several built-in or freely-available serializers that will work with a bare minimum of metadata; however, their usefulness would be sharply limited if they didn't allow you to customize the process to produce exactly the results you need. So, they do.

Usually your class/instance will have a lot of private fields and other public properties that are irrelavant for the XML.

Attributes like [XMLElement(...)] are also used to define a name of the XML element that never changes. Even if you change the name of the property in your class, serializing and desrializing will still work.

If you do not want to use these elements, you are free to implement your own XMLWriter or XMLReader. You can also create an instance of XMLWriter and use it's Write methods to write whatever your want.

Yes. You can do this with XmlSerializer if you don't mind configuring a XmlAttributeOverrides instance at runtime and passing that into the overloaded constructor. With this approach you can do everything you can do with XML attributes, but it is critical that you cache and re-use the serializer you create when doing this (don't create a new instance each time).

For binary, protobuf-net allows you to configure it at runtime via RuntimeTypeModel, for example RuntimeTypeModel.Default.Add(typeof(SomeClass), false).Add("X", "Y", "Z");. The reality, though, is that serializers are often complex with lots of options. In most cases, it is simply easier to keep the configuration with the entities. But yes: some do allow you to fully configure them at runtime.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top