Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can an existing object with only a parameterized constructor be targeted and serialized? #641

Open
aczolan opened this issue Feb 7, 2025 · 3 comments
Labels
question Further information is requested

Comments

@aczolan
Copy link

aczolan commented Feb 7, 2025

I am looking to use reflection to generically serialize objects to XML using this library. In my code I have an instance of each object to serialize and I know its type. The serialization looks something like this:

public void Serialize(ref object objectToSerialize, Type objectType, out string serializedXML)
{
  var serializer = new ConfigurationContainer()
  .EnableImplicitTyping(objectType)
  .Create();
  serializedXML = serializer.Serialize(new XmlWriterSettings { Indent = true }, objectToSerialize);
}

This works great until I run into an object whose type just so happens to not have a non-parameterized constructor. It seems that the solution listed in this library would be to try adding .EnableParameterizedContent() or .EnableParameterizedContentWithPropertyAssignments() on the ConfigurationContainer. These require following the listed rules for constructor parameters, and I would like to avoid having to enforce classes to have a specific parameter format on their constructors (the objects I am serializing come from all over our codebase, or potentially from external libraries). Again the goal here is to serialize objects generically; I'd prefer to not enforce these classes to follow any particular code style.

The thing is, in my example, I know that objectToSerialize is a real, non-null object. It has valid, non-null public properties that are ready for serialization. Is there a way to serialize these objects and their properties, without particularly caring if the class has a non-parameterized constructor or not? We have an instance of the object ready, is there a way to target that instance directly and serialize it, without caring about how it was constructed?

@aczolan aczolan added the question Further information is requested label Feb 7, 2025
@Mike-E-angelo
Copy link
Member

Hey there @aczolan thank you for writing in with your question. If I understand correctly, the problem you are facing is a common problem with every serialization solution out there, not just ours. You can (in theory) serialize all the properties, but the trick is ... how are you going to deserialize them on the other end? You need to have a contract (or set of rules) of some sort to have some guarantee on the other end that the object will be correctly materialized and assigned accordingly.

Now, if you are just emitting the object graph to make a document to see what it looks like, that makes more sense. But more times than not the graph is being serialized to be read back in later, and that is when we run into the challenge of getting it to materialize successfully back into memory.

So to answer your question, the object will need to have a parameterless constructor (i.e., follows the classical XmlSerializer) or it will have to make use of the Protobuf-inspired ruleset we've adopted for a well-defined parameter list for its intended constructor. Theoretically, you could make an extension using the extensibility framework that we have in place to do something exotic, but to be honest it's been so long since I have been in those parts that I am not entirely sure I would be helpful to assist there in a viable way. 🤔

If you have any more questions about this please feel free to ask and I can see if I can further assist. 👍

@aczolan
Copy link
Author

aczolan commented Feb 7, 2025

Thanks for the quick reply @Mike-E-angelo . I don't have an explicit contract set in my code per se, since the goal was for every subject class to be a POCO and ambiguous to how it was being serialized/deserialized (I know POCO is kind of a buzzword but we're trying to keep classes simple and cut down on any additional markup). Ideally the serializer/deserializer just reads/writes every property in the file and reads/writes the values in the existing object's properties where possible. I accomplished this before using C# reflection, but now I'm looking into if I can leverage this library instead.

I'm mostly just making sure that I wasn't missing something obvious or if there is some way to do everything based on existing object references, without creating brand-new objects at deserialization time. The IExtendedXmlSerializer has a .UsingTarget method for deserialization, which seems be this exact behavior, but that still follows the required constructor rules in the target class.

I can take a look more into the extension framework you mentioned.

@Mike-E-angelo
Copy link
Member

Mike-E-angelo commented Feb 7, 2025

Thanks for the quick reply @Mike-E-angelo .

Sure thing. 😃👍

Ideally the serializer/deserializer just reads/writes every property in the file and reads/writes the values in the existing object's properties where possible

So to be sure, if the object has a parameterless constructor this will happen. This follows .NET conventions for json/xml serialization. 👍

I can take a look more into the extension framework you mentioned.

Here's a good starting point: https://github.com/ExtendedXmlSerializer/home/wiki/Example-Scenarios#monitor-serialization-pipeline

There is also the ISerializationInterceptor which may be a good candidate for your use case here: #451

If you encounter any further questions along those paths please let me know and we'll see if we can figure it out.

GitHub
A configurable and eXtensible Xml serializer for .NET. - ExtendedXmlSerializer/home

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants