-
-
Notifications
You must be signed in to change notification settings - Fork 485
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
Determining the type from a field #343
Comments
I have a similar need when dealing with polymorphic objects. Is there an example for |
I also have a similar need. My current workaround is a two phase serialization. I first deserialize to Dictionary<object,object>, then traverse the key value pairs and when I have determined the type (kind), I serialize the value and deserialize it using the determined type. It's ugly, but it works. |
I've implemented variations on this problem with a slightly different 2-phase deserialization. Here's three different ways to handle similar situations. Polymorphic Document Type
Use a Tag to Indicate the Concrete Type Yaml
C# using
C# using custom
Resolving a Reference to an External Object Yaml:
C# (trimmed on the fly, so it may have errors)
|
Thanks @thisisthedave. This helped a lot. I originally wanted to parse
Which could result in a document as follows:
I think I can do that with tags as you described. |
I'm sorry I was unable to answer this question in a timely fashion. As you have certainly moved on to other things, I will close this issue, but feel free to reopen it if this is still an issue. |
@aaubry no worries. Could you tell me which of the approaches you would recommend? I.e. which primitive in YamlDotNet is best to solve this problem? |
Currently there's no good way to achieve this, besides the two passes that were described above. This would definitely be useful but it is not clear how this could be achieved with the current implementation. The problem is that the deserializer was designed to work in a streaming fashion, as the YAML specification suggests. This means that as soon as we encounter a key, we need to be able to determine which property it will correspond to, therefore the destination type must already be known. |
I want to achieve polymorphism in YAML like this:
Foo is a property on a class and it is declared as abstract type, say FooBase. FooTypeA is the name of the concrete class that inherits from FooBase. SomeProperty and SomeOtherProperty are properties on FooTypeA. This is how Ansible YAML files are structured, so I am not the only one who follows this pattern. There doesn't seem to be a way to get YamlDotNet to allow this. INodeTypeResolver looks promising, but it only gets MappingStart and I can't see the scalar after that to read FooTypeA and direct it accordingly. How can I get access to IParser in INodeTypeResolver. I have absolutely no clue what to do with INodeDeserializer if I am supposed to use that. |
I also had need for abstract type resolving. I prototyped a solution which I am currently using. Please see: https://gist.github.com/atruskie/bfb7e9ee3df954a29cbc17bdf12405f9 In short, it replaces the ObjectNodeDeserializer. When it encounters a known abstract type or interface it buffers all nodes for the current mapping and sends that buffer to code ( It's cool because any part of a yaml document could be used to determine which child type should be used (including comments theoretically). In my gist I included two type discriminators that I made for my purpose:
Hope this helps! @aaubry if my solution even remotely passes for what you'd consider an optimal solution, I'll turn it into a PR |
Any updates on this issue (serialization of abstract types)? I thought also of implementing the "higher level serializer" which checks if the type is derived and "lover serializer" which its only job is to write the actual yaml text to a file, but it may harm the performance... |
@pmikstacki to deserialize any type, where the type name is encoded in a key, read the value of some key in the type resolver and use reflection to instantiate the type instance. Be warned though, this is super dangerous from a security point if view. More likely, you'll have a limited set of types you'll want to allow to be deserialized. In that case you can use reflection to iterate over all sub classes of an abstract type (or all implementers of an interface) and add them to the allowed ties at app startup. |
Since there are multiple solutions to this problem listed in here, I'm going to close this issue. |
I want do deserialize Kubernetes YAML that looks like this:
The type of the object (what other fields besides
apiVersion
andkind
the object will have) is determined by thekind
field. Depending on the value ofkind
, I need to map this YAML to e.g. either aService
or aDeployment
model class.I tried TypeResolvers and TypeConverters but couldn't figure it out. Is this possible somehow with YamlDotNet?
The text was updated successfully, but these errors were encountered: