6

I have tried to implement Source Generation-based JSON serilization, based on MS Docs: How to use source generation in System.Text.Json. My code is as follows:

using System;
using System.Text.Json;

var person = new Person(){FirstName = "John", LastName = "Shepard"};
Console.WriteLine(JsonSerializer.Serialize(person));

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

And my SerializationContext:

[JsonSerializable(typeof(Person))]
public partial class PersonJsonContext : JsonSerializerContext
{

}

I have the System.Text.Json version 6.0.0 installed in my project.

But when running dotnet build, no code is generated in my PersonJsonContext class. Where can I find the generated code?

CodeCaster
  • 147,647
  • 23
  • 218
  • 272
Ombrelin
  • 547
  • 1
  • 8
  • 27
  • 1
    _"no code is generated in my PersonJsonContext class"_ - it doesn't generate _code_ in source files, it generates serialization classes in your assembly. – CodeCaster Nov 16 '21 at 15:42
  • Okay, I see, I got confused because I watched a video where the guy had a .g.cs file with all the generated code produced. So if I understand well, in my current code, the source-gen based serialization is effectively used ? – Ombrelin Nov 16 '21 at 15:45
  • 1
    Yes the intermediate step is a .g.cs file, but this won't overwrite your source files or add to them. The other half of the partial (being in that .g.cs file) will be compiled into your assembly. You then use it as in the tutorial. – CodeCaster Nov 16 '21 at 15:46
  • Okay, but is it normal that the .g.cs file does not appear in my file system ? Is it cleared after the compilation process ? How can I verify that my serialization effectively uses the source gen ? – Ombrelin Nov 16 '21 at 15:48

1 Answers1

8

A source generator generates source code in as an intermediate compilation step. As input, it has your code annotated with opt-in attributes, and as output it has C# files that will get compiled into your final assembly.

Using Visual Studio 2019 version 16.9 or higher you can expand the Analyzers section under the Dependencies of your project tree to see the generated code: Dependencies -> Analyzers

You can also browse the files by opening your output directory, the .g.cs files should be in the obj directory by default.

Now the [JsonSerializable] attribute opt-in for the System.Text.Json serializers makes the compiler output classes that aid in serialization, so you won't take a performance hit when you first serialize or deserialize to or from a certain class, but offload this performance hit to the compilation phase.

Without code generators, System.Text.Json inspects the type for serialization metadata when it first encounters a type, caching it for the remainder of the application lifetime.

If you apply the appropriate attributes and inspect your output directory, and you actually use the context during (de)serialization, you'll notice when it didn't work.

Just be sure to pass the context for the appropriate type:

var json = JsonSerializer.Serialize(person, PersonJsonContext.Default.Person);
canton7
  • 37,633
  • 3
  • 64
  • 77
CodeCaster
  • 147,647
  • 23
  • 218
  • 272
  • Found it in the [release notes](https://learn.microsoft.com/en-us/visualstudio/releases/2019/release-notes-v16.9) – canton7 Apr 26 '22 at 08:15
  • 1
    @canton7 so you're saying this was already possible when I posted this answer... Thanks! – CodeCaster Apr 27 '22 at 09:32