This project is to migrate the XmlSerializer generator (sgen) infrastructure to run as a source generator.
- The existing code heavily relies on System.Reflection to interrogate the types and we want to reuse as much of the code as possible. https://github.com/davidfowl/Roslyn.Reflection can help with that
- The System.Reflection code expected to be able to get the attributes as their actual runtime objects. A translation layer added on top of Roslyn.Reflection helps with that
- Type equality is expected. The pattern of
Type.Equals(OtherType)works fine, howeverType == OtherTypedoes not seem to work (the==operator explicitly fails if only oneside is aRuntimeType). Other checks, such asIsAssignableFromneed to be reworked as well - There is a lot of duplication of code from
dotnet/runtimesince there are internal members we need. Currently, they're the same name as the ones that are even exposed publicly, but are local to the project (the warning is disabled to hide that fact).
The following is an example of how you can opt into the generator:
using System.Xml.Serialization;
// Utilize the generated serializer
Serializers.MyClass.Serialize(Console.Out, new MyClass { Value = 5 });
// Get a serializer
Serializers.Get(typeof(MyClass)).Serialize(Console.Out, new MyClass { Value = 5 });
// POCO to be serialized
public class MyClass
{
public int Value { get; set; }
public int Value2 { get; set; }
public int[] Values { get; set; } = null!;
public List<string> Values2 { get; set; } = null!;
}
// Let the generator know what type to serialize. It will generate a static member of
// type XmlSerializer within this class with the name of the supplied type
[XmlSerializable(typeof(MyClass))]
partial class Serializers
{
}NOTE: This requires C#12 and a newish SDK. If that doesn't work, use the options above.
The following shows how to opt into an interceptor that will override calls to the registered method. There are two ways to register overrides:
- In your csproj, add a property such as
<SgenMethodOverride>Test.Get(System.Type)</SgenMethodOverride>. - In your project with an assembly level attribute:
[assembly: XmlSerializerOverride(typeof(Test), nameof(Test.Get))]
using System.Xml.Serialization;
[assembly: XmlSerializerOverride(typeof(Test), nameof(Test.Get))]
Test.Get(typeof(MyClass)).Serialize(Console.Out, new MyClass { Value = 5 });
Console.ReadLine();
class Test
{
public static XmlSerializer Get(Type type)
{
throw new NotImplementedException();
}
}
//// POCO to be serialized
class MyClass
{
public int Value { get; set; }
public int Value2 { get; set; }
public int[] Values { get; set; } = null!;
public List<string> Values2 { get; set; } = null!;
}The samples/test-generator project is hooked up to run the analyzer and with the latest VS versions, it will automatically reload if there are changes.
You can launch the src/XmlSerializer2 project to debug into the source generator.
If you want to try this out, you can either use the GitHub package feed for my account (it requires auth setup) or you can download the package and add it to a local feed.
