-
-
Notifications
You must be signed in to change notification settings - Fork 491
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
support net 7's native aot #740
Comments
When I get some time I’ll work on this. Not sure what it will take because we heavily use reflection, but supporting current frameworks and features is important. In the meantime, if you want to take a look at it we are happy to accept contributions. |
I’m still working on this. I got it to instantiate a class. It’s taking a lot of attributes on the methods so the classes and other objects don’t get stripped away. It also requires an attribute added to the class that gets deserialized so all of your yaml objects will require that as well. |
you might want to incorporate source generators. https://devblogs.microsoft.com/dotnet/introducing-c-source-generators/ |
Well that is an interesting idea @ivanjx . When I get some more time, I'll look in to them. |
Just to give you an update on this. I have a code generator/analyzer that will generate static factories for classes and property/field accessesors. It works for primitive types and anything marked with a I have not merged any of this in yet since it's not ready just yet. I just wanted to let you know that I am making progress on getting this done. I am hoping to have this all done and ready by end of week. |
If you want to check out what I've got, here's my branch: https://github.com/EdwardCooke/YamlDotNet/tree/ec-aot The demo app that shows how to implement it is in the |
thank you for your great job! |
Pending a review of the PR I just made, we'll have the code in place in the main YamlDotNet library to support the AoT/Trimmed version of the library. Once approved and approved and merged in, I will push up a NuGet package containing the analyzer that you can try out to make sure it meets your needs. |
K, I just merged in my PR with necessary changes to the library for the analyzer. I'll try and push up a test instance of the analyzer, hopefully this week, But with Christmas coming up, it may not happen. In the meantime, you are more than welcome to test out the analyzer on your own, Just take a look at the Core7AoTCompileTest project to see how to reference the project. |
Ok, I have the code generator pushed up. The package name is Here is an example, working code To run that repo example
|
which part of the library that throws IL3050? is it possible to remove or isolate those? |
The warnings are next on the list but won’t be until later. If you want to take a stab at it that would be great. What I was thinking was try a static builder that doesn’t reference the reflection based stuff and see if it goes away. |
Ok. I got the warnings resolved. Here's what needs to be done to check it out Update the static generator package to the latest, 0.0.3 When doing an AoT/trimmed library, instead of using SerializerBuilder and DeserializeBuilder use the StaticSerializerBuilder and StaticDeserializerBuilder. There should be a couple of warnings that will show up when using the current SerializerBuilder and DeserializerBuilder and AoT/trimming. The static ones don't use reflection anywhere, thus, no warnings. There was a bunch of areas in YamlDotNet that was generating generic classes when a custom dictionary object didn't implement IDictionary or a custom list didn't implement IList. That's probably the biggest limitation in the static version, and I couldn't find a way around it. My testing showed that the static builders worked for the simple serialization without showing any warnings. I'll be working on setting up unit tests for the static implementation over the next bit. If you don't find any issues, I'll bring those changes in to the master branch when the unit tests are complete and push a new version. There are some minor breaking changes in some of the underlying interfaces/classes, namely the IObjectFactory, there is a new class, ObjectFactoryBase that can be inherited from, which will cover the current implementation without needing to write any additional code or other changes. If you manually instantiated some of the node deserializers, there will need to be code changes, they now take in a ITypeFactory and/or IObjectFactory object. Those changes were necessary to break out the rest of the reflection implementation so it could be replaced with the static implementation. |
Have you had a chance to try out the versions I posted? Did they do what you needed? |
hi @EdwardCooke i will try them out once im back from vacation as soon as possible. i will try this or if you have updated steps of how to try out your changes please let me know. thanks for your great work! |
sorry for the late response. i have added these to my csproj (netstandard2.0) and removed the original ones:
however i cant seem to be able to resolve |
i also got these when i tried to build:
|
this is my class:
|
No worries on the late response, I hope your vacation was great! It almost looks like your project may still be referencing the official yamldotnet library somewhere. I just pulled my nuget package manually and inspected it with ILSpy and the classes are there. Also, records won't work with the static serializer, if I recall they have to be fully initialized when constructed, as in, we can't set the properties after the object is created. The static generator also doesn't recognize them as objects that can be deserialized. I can fix that, but, since the compiler won't let you set properties on a record, not sure if it's worth that, except for the serializing piece. The reason they work with the non-aot style of the deserializer is that it bypasses the compiler and uses reflection, which does work to set properties. Not much I can do there for deserialization, sorry. This example did expose a bug in the code generator though, nullable properties don't get generated correctly and it throws an error when trying to compile. The error you will receive is:
I'll work on that and get a new version of the static generator out. |
ok then seems you are right about the static deserializer class since the errors i see on the build are just |
I just published 0.0.2-aot of |
i get these warnings:
|
ok it seems that the second warning is because i am using the deserializer in a shared project and i use that shared project in another project (avalonia) so that the source is generated twice on both projects. build with |
this is the generated source for the project that is not using the YamlDotNet. seems empty here while in the shared project it generates with the information of the types.
|
as for the
as shown here |
I’ll fix the warnings when I get some time. Thanks for the link. |
great. i will try it tomorrow if possible. also does your deserializer support array? i would be using it like |
It should handle it without an issue. I will test that when I get a minute today to verify. |
Hey both, I'm also interested in aot support for YamlDotNet and have got your One issue I've found is that classes with inheritance are not able to deserialise inherited members. I was able to fix the issue by changing the following lines: var members = classSymbol.GetMembers();
foreach (var member in members)
{
if (member.IsStatic ||
member.DeclaredAccessibility != Accessibility.Public ||
member.GetAttributes().Any(x => x.AttributeClass!.ToDisplayString() == "YamlDotNet.Serialization.YamlIgnoreAttribute"))
{
continue;
}
if (member is IPropertySymbol propertySymbol)
{
classObject.PropertySymbols.Add(propertySymbol);
CheckForSupportedGeneric(propertySymbol.Type);
}
else if (member is IFieldSymbol fieldSymbol)
{
classObject.FieldSymbols.Add(fieldSymbol);
CheckForSupportedGeneric(fieldSymbol.Type);
}
} To include a while loop that loops down through base classes: var currentSymbol = classSymbol;
do
{
var members = currentSymbol.GetMembers();
foreach (var member in members)
{
if (member.IsStatic ||
member.DeclaredAccessibility != Accessibility.Public ||
member.GetAttributes().Any(x => x.AttributeClass!.ToDisplayString() == "YamlDotNet.Serialization.YamlIgnoreAttribute"))
{
continue;
}
if (member is IPropertySymbol propertySymbol)
{
classObject.PropertySymbols.Add(propertySymbol);
CheckForSupportedGeneric(propertySymbol.Type);
}
else if (member is IFieldSymbol fieldSymbol)
{
classObject.FieldSymbols.Add(fieldSymbol);
CheckForSupportedGeneric(fieldSymbol.Type);
}
}
currentSymbol = currentSymbol.BaseType;
}
while (currentSymbol.BaseType is not null); I've not used source generators before and I'm not across YamlDotNet internals so I have no idea if this is a comprehensive solution or not, but hopefully its useful to someone 😅 Is there anything I can do to help/test aot support for YamlDotNet? It's a very useful feature for me 😊 |
Thanks for finding that. I’ll make the change and get an updated test library up shortly. There’s this now and another one to support list and array as base objects that I want to do. Hopefully today. |
Check out 0.0.5-aot of |
Got my tests done, found a bug with using List as the root instead of array, using 0.0.6-aot of |
I'm getting a build error with the new versions @EdwardCooke, it may be something stale in my pipeline but I think I've cleared everything and it still persists. Any help would be greatly appreciated (:
When I pull your |
I’ll push them up again with new versions later tonight just to make sure they are latest. |
Thank you! 🙏 |
There should be a 1.0.0-aot version of both packages up there now. |
The code is merged in master, however, the nuget api key is most likely scoped to only allow the YamlDotNet library to be pushed up since it failed trying to push up the new static generator package. That will need to be allowed by @aaubry, until it is, there won't be an "official" one, but, I will keep mine updated with the official code base. |
Version 13.0.0 of the static generator and yamldotnet is available. |
@EdwardCooke |
closing this as i got it to work with version 13.0.0 |
@ivanjx I suspect you already know, yes, you still need to use the Vecc static analyzer package. |
one more issue is that the static generator does not support nested class, for example:
currently it cannot find |
I’ll see what I can do about adding that. I think you could mark the class as internal which would at least hide it from other libraries. |
A new version has been pushed up supporting nested classes. If theres any additional work needed, open up a new issue, this one's kind of long. |
@EdwardCooke would it be possible to add support for multiple static contexts ? With |
You want the serializer/deserializer to work with multiple of them? I think that could actually be relatively easy to do. We would need to add a method to the serializer context to return whether the type is supported, then create a combined serializer context that accepts all of the contexts and does a for each. Or something that. Do you want to to do it? It might be a few days before I can get to it. |
Yes that was my idea - I already did my own "combined context" but I didnt like to catch the exception to move on to the next context. I will submit a PR ... |
Great! If you can open a new issue and reference that it would be fantastic. |
Is your feature request related to a problem? Please describe.
i cant use this library with native aot on net 7 because this uses system.reflection.
Describe the solution you'd like
a solution similar to system.text.json is to use source generator.
Describe alternatives you've considered
excluding the types that i want to deserialize in
rd.xml
works.Additional context
https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/
The text was updated successfully, but these errors were encountered: