From 1aa40b62d43d34b696a9ba290b32ab17736f1bf8 Mon Sep 17 00:00:00 2001 From: Tom Dykstra Date: Mon, 18 Oct 2021 15:43:46 -0700 Subject: [PATCH 01/11] draft --- docs/fundamentals/toc.yml | 4 +- .../system-text-json-overview.md | 20 ++- ...ystem-text-json-source-generation-modes.md | 139 ++++++++++++++++++ .../system-text-json-source-generation.md | 86 +---------- 4 files changed, 159 insertions(+), 90 deletions(-) create mode 100644 docs/standard/serialization/system-text-json-source-generation-modes.md diff --git a/docs/fundamentals/toc.yml b/docs/fundamentals/toc.yml index 177c87837a13b..e6fd15e873119 100644 --- a/docs/fundamentals/toc.yml +++ b/docs/fundamentals/toc.yml @@ -2008,6 +2008,8 @@ items: - name: Overview href: ../standard/serialization/system-text-json-overview.md displayName: json serialization + - name: Reflection vs. source generation + href: ../standard/serialization/system-text-json-source-generation.md - name: How to serialize and deserialize JSON href: ../standard/serialization/system-text-json-how-to.md - name: Control serialization behavior @@ -2040,7 +2042,7 @@ items: items: - name: Customize character encoding href: ../standard/serialization/system-text-json-character-encoding.md - - name: Source generation in System.Text.Json + - name: Use source generation href: ../standard/serialization/system-text-json-source-generation.md - name: Write custom converters href: ../standard/serialization/system-text-json-converters-how-to.md diff --git a/docs/standard/serialization/system-text-json-overview.md b/docs/standard/serialization/system-text-json-overview.md index 08dc204253b74..495ca0c582a60 100644 --- a/docs/standard/serialization/system-text-json-overview.md +++ b/docs/standard/serialization/system-text-json-overview.md @@ -1,7 +1,7 @@ --- title: "Serialize and deserialize JSON using C# - .NET" description: This overview describes the System.Text.Json namespace functionality for serializing to and deserializing from JSON in .NET. -ms.date: 07/21/2021 +ms.date: 10/18/2021 no-loc: [System.Text.Json, Newtonsoft.Json] zone_pivot_groups: dotnet-version helpviewer_keywords: @@ -21,14 +21,22 @@ The library also provides classes for working with an in-memory document object There are some limitations on what parts of the library that you can use from Visual Basic code. For more information, see [Visual Basic support](system-text-json-how-to.md#visual-basic-support). +## Run-time Reflection vs. compile-time source generation + +By default, `System.Text.Json` uses run-time [Reflection](../../csharp/programming-guide/concepts/reflection.md) to gather the metadata it needs to access properties of objects for serialization and deserialization. As an alternative, `System.Text.Json` can use the C# [source generation](../../csharp/roslyn-sdk/source-generators-overview.md) feature to improve performance, reduce private memory usage, and facilitate [assembly trimming](../../core/deploying/trimming/trim-self-contained.md), which reduces app size. For information about how to choose between Reflection and source generation, see [Source generation modes in System.Text.Json](system-text-json-source-generation-modes). + ## How to get the library -* The library is built-in as part of the shared framework for .NET Core 3.0 and later versions. -* For earlier framework versions, install the [System.Text.Json](https://www.nuget.org/packages/System.Text.Json) NuGet package. The package supports: +The library is built-in as part of the shared framework for .NET Core 3.0 and later versions. The source generation modes are built-in as part of the shared framework for .NET 6.0 and later versions. + +For framework versions earlier than .NET Core 3.0, install the [System.Text.Json](https://www.nuget.org/packages/System.Text.Json) NuGet package. The package supports: + +* .NET Standard 2.0 and later +* .NET Framework 4.7.2 and later +* .NET Core 2.1 and later +* .NET 5 and later - * .NET Standard 2.0 and later versions - * .NET Framework 4.7.2 and later versions - * .NET Core 2.0, 2.1, and 2.2 +Use of the Source generation features requires System.Text.Json 6.0 or later and .NET 5 SDK or later. ## Security information diff --git a/docs/standard/serialization/system-text-json-source-generation-modes.md b/docs/standard/serialization/system-text-json-source-generation-modes.md new file mode 100644 index 0000000000000..01b67ae0905f7 --- /dev/null +++ b/docs/standard/serialization/system-text-json-source-generation-modes.md @@ -0,0 +1,139 @@ +--- +title: How to use source generation in System.Text.Json +description: "Learn how to choose Reflection or source generation in System.Text.Json." +ms.date: 10/18/2021 +no-loc: [System.Text.Json] +zone_pivot_groups: dotnet-version +dev_langs: + - "csharp" + - "vb" +helpviewer_keywords: + - "JSON serialization" + - "serializing objects" + - "serialization" + - "objects, serializing" +ms.topic: how-to +--- + +# How to choose Reflection or source generation in System.Text.Json + +:::zone pivot="dotnet-6-0" +> [!IMPORTANT] +> Some information relates to prerelease product that may be substantially modified before it's released. Microsoft makes no warranties, express or implied, with respect to the information provided here. + +By default, `System.Text.Json` uses run-time Reflection to gather the metadata it needs to access properties of objects for serialization and deserialization. As an alternative, `System.Text.Json` can use the C# [source generation](../../csharp/roslyn-sdk/source-generators-overview.md) feature to improve performance, reduce private memory usage, and facilitate [assembly trimming](../../core/deploying/trimming/trim-self-contained.md), which reduces app size. + +You can use version 6.0 of System.Text.Json in projects that target earlier frameworks. For more information, see [How to get the library](system-text-json-overview.md#how-to-get-the-library). + +[The .NET 6.0 version of this article](system-text-json-source-generation-modes.md?pivots=dotnet-6-0) explains the options and gives guidance on how to choose the best approach for your scenario. +:::zone-end + +:::zone pivot="dotnet-5-0,dotnet-core-3-1" +[System.Text.Json](system-text-json-overview.md) version 6.0 and later can use the C# [source generation](../../csharp/roslyn-sdk/source-generators-overview.md) feature to improve performance, reduce private memory usage, and improve [assembly trimming](../../core/deploying/trimming/trim-self-contained.md) accuracy. You can use version 6.0 of System.Text.Json in projects that target earlier frameworks. For more information, see: + +* [The .NET 6.0 version of this article](system-text-json-source-generation-modes.md?pivots=dotnet-6-0). +* [How to get the library](system-text-json-overview.md#how-to-get-the-library) + +:::zone-end + +:::zone pivot="dotnet-6-0" + +## Introduction to System.Text.Json metadata + +To serialize or deserialize a type, needs information about how to access the members of the type. `JsonSerializer` needs the following information: + +* How to access property getters and fields for serialization. +* How to access a constructor, property setters, and fields for deserialization. +* Attributes that have been used to customize serialization or deserialization. +* Run-time configuration from . + +This information is referred to as *metadata*. + +## Metadata collection modes + +By default, `JsonSerializer` collects metadata at run time by using [Reflection](../../csharp/programming-guide/concepts/reflection.md). Whenever `JsonSerializer` has to serialize or deserialize a type for the first time, it collects and caches this metadata. The metadata collection process takes time and uses memory. + +You can use source generation to move the metadata collection process from run time to compile time. During compilation, the metadata is collected and source code files are generated. The generated source code files are automatically compiled as an integral part of the application. This compile-time metadata collection eliminates run-time metadata collection, which improves performance of both serialization and deserialization. + +## Serialization optimization mode + +`JsonSerializer` has many features that customize the output of serialization, such as [camel-casing property names](system-text-json-customize-properties.md#use-camel-case-for-all-json-property-names) and [preserving references](system-text-json-preserve-references.md#preserve-references-and-handle-circular-references). Support for all those features causes some performance overhead. Source generation can improve serialization performance by generating optimized code that uses [`Utf8JsonWriter`](system-text-json-use-dom-utf8jsonreader-utf8jsonwriter.md#use-utf8jsonwriter) directly. + +The optimized code doesn't support all of the serialization features that `JsonSerializer` supports. The serializer detects whether the optimized code can be used and falls back to default serialization code if unsupported options are specified. For example, is not applicable to writing, so specifying this option doesn't cause a fall-back to default code. + +The following table shows which options in `JsonSerializerOptions` are supported by the optimized serialization code: + +| Serialization option | Supported by optimized code | +|------------------------------------------------------------------------|-----------------------------| +| | ❌ | +| | ✔️ | +| | ❌ | +| | ❌ | +| | ❌ | +| | ✔️ | +| | ✔️ | +| | ✔️ | +| | ❌ | +| | ✔️ | +| | ❌ | +| | ✔️ | + +The following table shows which attributes are supported by the optimized serialization code: + +| Attribute | Supported by optimized code | +|-------------------------------------------------------------------|-----------------------------| +| | ❌ | +| | ❌ | +| | ✔️ | +| | ✔️ | +| | ❌ | +| | ✔️ | + +If a non-supported option or attribute is specified for a type, the serializer falls back to the default `JsonSerializer` code. In that case the optimized code isn't used when serializing that type but may be used for other types. + +## Choose Reflection or a source generation mode + +Choose Reflection or source generation modes based on the following benefits that each one offers: + +| Benefit | Reflection | Metadata collection | Serialization optimization | +|-------------------------------------------|------------|---------------------|----------------------------| +| Simple to code and debug. | ✔️ | ❌ | ❌ | +| Reduces start-up time. | ❌ | ✔️ | ❌ | +| Reduces private memory usage. | ❌ | ✔️ | ✔️ | +| Eliminates run-time reflection. | ❌ | ✔️ | ✔️ | +| Facilitates trim-safe app size reduction. | ❌ | ✔️ | ✔️ | +| Increases serialization throughput. | ❌ | ❌ | ✔️ \* | + +The performance improvements provided by source generation can be substantial. For example, [test results](https://devblogs.microsoft.com/dotnet/try-the-new-system-text-json-source-generator/#how-source-generation-provides-benefits) have shown up to 40% or more startup time reduction, private memory reduction, throughput speed increase, and app size reduction. + +\* As explained in the [preceding section](#serialization-optimization-mode), the optimized code doesn't support some features. Do performance testing with your options and workloads to determine how much benefit you can actually get from serialization optimization mode. Also, the ability to fall back to `JsonSerializer` code requires metadata collection mode. If you select only serialization optimization mode, serialization might fail for types or options that need to fall back to `JsonSerializer` code. + +## Get the source generation functionality + +The source generation functionality of System.Text.Json 6.0 and later can be used in any .NET C# project, including class libraries and console, web, and Blazor applications. You can use version 6.0 of System.Text.Json in projects that target earlier frameworks. For more information, see [How to get the library](system-text-json-overview.md#how-to-get-the-library). + +For information about how to use source generation modes in code that uses System.Text.Json, see [How to use source generation in System.Text.Json](system-text-json-source-generation.md). +:::zone-end + +## See also + +* [Try the new System.Text.Json source generator](https://devblogs.microsoft.com/dotnet/try-the-new-system-text-json-source-generator/) +* [JSON serialization and deserialization in .NET - overview](system-text-json-overview.md) +* [How to use the library](system-text-json-how-to.md) +* [Instantiate JsonSerializerOptions instances](system-text-json-configure-options.md) +* [Enable case-insensitive matching](system-text-json-character-casing.md) +* [Customize property names and values](system-text-json-customize-properties.md) +* [Ignore properties](system-text-json-ignore-properties.md) +* [Allow invalid JSON](system-text-json-invalid-json.md) +* [Handle overflow JSON or use JsonElement or JsonNode](system-text-json-handle-overflow.md) +* [Preserve references and handle circular references](system-text-json-preserve-references.md) +* [Deserialize to immutable types and non-public accessors](system-text-json-immutability.md) +* [Polymorphic serialization](system-text-json-polymorphism.md) +* [Migrate from Newtonsoft.Json to System.Text.Json](system-text-json-migrate-from-newtonsoft-how-to.md) +* [Customize character encoding](system-text-json-character-encoding.md) +* [Use DOM, Utf8JsonReader, and Utf8JsonWriter](system-text-json-use-dom-utf8jsonreader-utf8jsonwriter.md) +* [Write custom converters for JSON serialization](system-text-json-converters-how-to.md) +* [DateTime and DateTimeOffset support](../datetime/system-text-json-support.md) +* [Supported collection types in System.Text.Json](system-text-json-supported-collection-types.md) +* [System.Text.Json API reference](xref:System.Text.Json) +* [System.Text.Json.Serialization API reference](xref:System.Text.Json.Serialization) diff --git a/docs/standard/serialization/system-text-json-source-generation.md b/docs/standard/serialization/system-text-json-source-generation.md index d698b6a43975f..0401dfdae01c2 100644 --- a/docs/standard/serialization/system-text-json-source-generation.md +++ b/docs/standard/serialization/system-text-json-source-generation.md @@ -21,96 +21,16 @@ ms.topic: how-to > [!IMPORTANT] > Some information relates to prerelease product that may be substantially modified before it's released. Microsoft makes no warranties, express or implied, with respect to the information provided here. -[System.Text.Json](system-text-json-overview.md) can use the C# [source generation](../../csharp/roslyn-sdk/source-generators-overview.md) feature to improve performance, reduce private memory usage, and facilitate [assembly trimming](../../core/deploying/trimming/trim-self-contained.md), which reduces app size. This article shows how to use the source generation features of System.Text.Json. +This article shows how to use the source generation features of [System.Text.Json](system-text-json-overview.md). :::zone-end :::zone pivot="dotnet-5-0,dotnet-core-3-1" -[System.Text.Json](system-text-json-overview.md) version 6.0 and later can use the C# [source generation](../../csharp/roslyn-sdk/source-generators-overview.md) feature to improve performance, reduce private memory usage, and improve [assembly trimming](../../core/deploying/trimming/trim-self-contained.md) accuracy. For information about how to use source generation in System.Text.Json, see [the .NET 6.0 version of this article](system-text-json-source-generation.md?pivots=dotnet-6-0). +For information about how to use source generation in System.Text.Json, see [the .NET 6.0 version of this article](system-text-json-source-generation.md?pivots=dotnet-6-0). :::zone-end :::zone pivot="dotnet-6-0" -## Source generation modes - -System.Text.Json provides two modes of source generation: - -* Metadata collection -* Serialization optimization - -You can use either mode by itself or in combination. - -### Metadata collection mode - -To serialize or deserialize a type, needs information about how to access the members of the type. To serialize, `JsonSerializer` needs to know how to access property getters and fields. To deserialize, it needs to know how to access a constructor, property setters, and fields. It also needs to know if any attributes have been used to customize serialization or deserialization. This information is referred to as *metadata*. Metadata also includes run-time configuration from . - -By default, `JsonSerializer` collects metadata at run time by using [Reflection](../../csharp/programming-guide/concepts/reflection.md). Whenever `JsonSerializer` has to serialize or deserialize a type for the first time, it collects and caches this metadata. The metadata collection process takes time and uses memory. - -You can use source generation to move the metadata collection process from run time to compile time. During compilation, the metadata is collected and source code files are generated. The generated source code files are automatically compiled as an integral part of the application. This compile-time metadata collection eliminates run-time metadata collection, which improves performance of both serialization and deserialization. - -### Serialization optimization mode - -`JsonSerializer` has many features that customize the output of serialization, such as [camel-casing property names](system-text-json-customize-properties.md#use-camel-case-for-all-json-property-names) and [preserving references](system-text-json-preserve-references.md#preserve-references-and-handle-circular-references). Support for all those features causes some performance overhead. Source generation can improve serialization performance by generating optimized code that uses [`Utf8JsonWriter`](system-text-json-use-dom-utf8jsonreader-utf8jsonwriter.md#use-utf8jsonwriter) directly. The optimized code doesn't support all of the serialization features that `JsonSerializer` supports. The serializer detects whether the optimized code can be used. For example, is not applicable to writing, so this option doesn't prevent the serializer from using the optimized code. - -The following table shows which options specified by `JsonSerializerOptions` are supported by the optimized serialization code: - -| Serialization option | Supported by optimized code | -|------------------------------------------------------------------------|-----------------------------| -| | ❌ | -| | ✔️ | -| | ❌ | -| | ❌ | -| | ❌ | -| | ✔️ | -| | ✔️ | -| | ✔️ | -| | ❌ | -| | ✔️ | -| | ❌ | -| | ✔️ | - -The following table shows which attributes are supported by the optimized serialization code: - -| Attribute | Supported by optimized code | -|-------------------------------------------------------------------|-----------------------------| -| | ❌ | -| | ❌ | -| | ✔️ | -| | ✔️ | -| | ❌ | -| | ✔️ | - -If a non-supported option or attribute is specified for a type, the serializer falls back to the default `JsonSerializer` code. In that case the optimized code isn't used when serializing that type but may be used for other types. - -### Choose a source generation mode - -Choose one or both source generation modes based on the following benefits that each one offers: - -| Benefit | Metadata collection | Serialization optimization | -|-------------------------------------------|---------------------|----------------------------| -| Reduces start-up time. | ✔️ | ❌ | -| Reduces private memory usage. | ✔️ | ✔️ | -| Eliminates run-time reflection. | ✔️ | ✔️ | -| Facilitates trim-safe app size reduction. | ✔️ | ✔️ | -| Increases serialization throughput. | ❌ | ✔️ \* | - -The performance improvements can be substantial. For example, [test results](https://devblogs.microsoft.com/dotnet/try-the-new-system-text-json-source-generator/#how-source-generation-provides-benefits) have shown up to 40% or more startup time reduction, private memory reduction, throughput speed increase, and app size reduction. - -\* As explained in the [preceding section](#serialization-optimization-mode), the optimized code doesn't support some features. Do performance testing with your options and workloads to determine how much benefit you can actually get from serialization optimization mode. Also, the ability to fall back to `JsonSerializer` code requires metadata collection mode. If you select only serialization optimization mode, serialization might fail for types or options that need to fall back to `JsonSerializer` code. - -## Get the source generation functionality - -The source generation functionality for System.Text.Json can be used in any .NET C# project, including class libraries and console, web, and Blazor applications. It can be used with .NET 5.0 SDK or later and with the following target frameworks: - -* .NET Core 2.1 and later -* .NET 5 and later -* .NET Framework 4.7.2 and later -* .NET Standard 2.0 and later - -For projects that target .NET 6 or later, there's no need to install the [System.Text.Json NuGet package](https://www.nuget.org/packages/System.Text.Json) because source generation is included in the runtime. - -For other target frameworks, install the latest preview version of the package. - -## Use source generation +## Use source generation defaults To use source generation with all defaults (both modes, default options): From 7a7c5ac1404867860ba55e7dfde02b49a9b80a12 Mon Sep 17 00:00:00 2001 From: Tom Dykstra Date: Mon, 18 Oct 2021 16:26:13 -0700 Subject: [PATCH 02/11] draft --- .../system-text-json-overview.md | 2 +- ...ystem-text-json-source-generation-modes.md | 28 +++++++++++++++++-- .../system-text-json-source-generation.md | 2 +- 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/docs/standard/serialization/system-text-json-overview.md b/docs/standard/serialization/system-text-json-overview.md index 495ca0c582a60..a287251534753 100644 --- a/docs/standard/serialization/system-text-json-overview.md +++ b/docs/standard/serialization/system-text-json-overview.md @@ -23,7 +23,7 @@ There are some limitations on what parts of the library that you can use from Vi ## Run-time Reflection vs. compile-time source generation -By default, `System.Text.Json` uses run-time [Reflection](../../csharp/programming-guide/concepts/reflection.md) to gather the metadata it needs to access properties of objects for serialization and deserialization. As an alternative, `System.Text.Json` can use the C# [source generation](../../csharp/roslyn-sdk/source-generators-overview.md) feature to improve performance, reduce private memory usage, and facilitate [assembly trimming](../../core/deploying/trimming/trim-self-contained.md), which reduces app size. For information about how to choose between Reflection and source generation, see [Source generation modes in System.Text.Json](system-text-json-source-generation-modes). +By default, `System.Text.Json` uses run-time [Reflection](../../csharp/programming-guide/concepts/reflection.md) to gather the metadata it needs to access properties of objects for serialization and deserialization. As an alternative, `System.Text.Json` can use the C# [source generation](../../csharp/roslyn-sdk/source-generators-overview.md) feature to improve performance, reduce private memory usage, and facilitate [assembly trimming](../../core/deploying/trimming/trim-self-contained.md), which reduces app size. For information about how to choose between Reflection and source generation, see [Source generation modes in System.Text.Json](system-text-json-source-generation-modes.md). ## How to get the library diff --git a/docs/standard/serialization/system-text-json-source-generation-modes.md b/docs/standard/serialization/system-text-json-source-generation-modes.md index 01b67ae0905f7..01187be780b70 100644 --- a/docs/standard/serialization/system-text-json-source-generation-modes.md +++ b/docs/standard/serialization/system-text-json-source-generation-modes.md @@ -1,5 +1,5 @@ --- -title: How to use source generation in System.Text.Json +title: How to choose Reflection or source generation in System.Text.Json description: "Learn how to choose Reflection or source generation in System.Text.Json." ms.date: 10/18/2021 no-loc: [System.Text.Json] @@ -49,12 +49,33 @@ To serialize or deserialize a type, needs This information is referred to as *metadata*. -## Metadata collection modes +## Metadata collection using source generation By default, `JsonSerializer` collects metadata at run time by using [Reflection](../../csharp/programming-guide/concepts/reflection.md). Whenever `JsonSerializer` has to serialize or deserialize a type for the first time, it collects and caches this metadata. The metadata collection process takes time and uses memory. You can use source generation to move the metadata collection process from run time to compile time. During compilation, the metadata is collected and source code files are generated. The generated source code files are automatically compiled as an integral part of the application. This compile-time metadata collection eliminates run-time metadata collection, which improves performance of both serialization and deserialization. +### Limitations of source generation metadata + +The following `JsonSerializer` features are not supported in metadata collection mode using source generation: + +| Feature +|------------------------------------------------------------------------| +| [Init-only properties](xref:System.Text.Json.Serialization.JsonIncludeAttribute) | +| [Private members](xref:System.Text.Json.Serialization.JsonIncludeAttribute) | + + +The following table shows which attributes are supported by the optimized serialization code: + +| Attribute | Supported by optimized code | +|-------------------------------------------------------------------|-----------------------------| +| | ❌ | +| | ❌ | +| | ✔️ | +| | ✔️ | +| | ❌ | +| | ✔️ | + ## Serialization optimization mode `JsonSerializer` has many features that customize the output of serialization, such as [camel-casing property names](system-text-json-customize-properties.md#use-camel-case-for-all-json-property-names) and [preserving references](system-text-json-preserve-references.md#preserve-references-and-handle-circular-references). Support for all those features causes some performance overhead. Source generation can improve serialization performance by generating optimized code that uses [`Utf8JsonWriter`](system-text-json-use-dom-utf8jsonreader-utf8jsonwriter.md#use-utf8jsonwriter) directly. @@ -97,7 +118,8 @@ Choose Reflection or source generation modes based on the following benefits tha | Benefit | Reflection | Metadata collection | Serialization optimization | |-------------------------------------------|------------|---------------------|----------------------------| -| Simple to code and debug. | ✔️ | ❌ | ❌ | +| Simpler to code and debug. | ✔️ | ❌ | ❌ | +| Supports all available options. | ✔️ | ❌ | ❌ | | Reduces start-up time. | ❌ | ✔️ | ❌ | | Reduces private memory usage. | ❌ | ✔️ | ✔️ | | Eliminates run-time reflection. | ❌ | ✔️ | ✔️ | diff --git a/docs/standard/serialization/system-text-json-source-generation.md b/docs/standard/serialization/system-text-json-source-generation.md index 0401dfdae01c2..d37fe152e09fe 100644 --- a/docs/standard/serialization/system-text-json-source-generation.md +++ b/docs/standard/serialization/system-text-json-source-generation.md @@ -139,7 +139,7 @@ Here are the preceding examples in a complete program: ## Specify options by using `JsonSerializerOptions` -Some options of aren't supported by serialization optimization mode. Such options cause a fallback to the non-source-generated `JsonSerializer` code. For more information, see [Serialization optimization](#serialization-optimization-mode). +Some options of aren't supported by serialization optimization mode. Such options cause a fallback to the non-source-generated `JsonSerializer` code. For more information, see [Serialization optimization](system-text-json-source-generation-modes.md#serialization-optimization-mode). To specify options by using : From b39f5b6991f2f31f29f8917a80340655488f0633 Mon Sep 17 00:00:00 2001 From: Tom Dykstra Date: Tue, 19 Oct 2021 08:22:40 -0700 Subject: [PATCH 03/11] markdownlint --- .../serialization/system-text-json-source-generation-modes.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/standard/serialization/system-text-json-source-generation-modes.md b/docs/standard/serialization/system-text-json-source-generation-modes.md index 01187be780b70..0b5b774b683c7 100644 --- a/docs/standard/serialization/system-text-json-source-generation-modes.md +++ b/docs/standard/serialization/system-text-json-source-generation-modes.md @@ -64,7 +64,6 @@ The following `JsonSerializer` features are not supported in metadata collection | [Init-only properties](xref:System.Text.Json.Serialization.JsonIncludeAttribute) | | [Private members](xref:System.Text.Json.Serialization.JsonIncludeAttribute) | - The following table shows which attributes are supported by the optimized serialization code: | Attribute | Supported by optimized code | From 0bdb8a4e4e768bee0cfa20d10cfa01b17f8ab134 Mon Sep 17 00:00:00 2001 From: Tom Dykstra Date: Tue, 19 Oct 2021 12:51:20 -0700 Subject: [PATCH 04/11] draft --- ...ystem-text-json-source-generation-modes.md | 37 ++++++++++--------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/docs/standard/serialization/system-text-json-source-generation-modes.md b/docs/standard/serialization/system-text-json-source-generation-modes.md index 0b5b774b683c7..fdb52c9f5d0cb 100644 --- a/docs/standard/serialization/system-text-json-source-generation-modes.md +++ b/docs/standard/serialization/system-text-json-source-generation-modes.md @@ -38,7 +38,7 @@ You can use version 6.0 of System.Text.Json in projects that target earlier fram :::zone pivot="dotnet-6-0" -## Introduction to System.Text.Json metadata +## System.Text.Json metadata To serialize or deserialize a type, needs information about how to access the members of the type. `JsonSerializer` needs the following information: @@ -49,31 +49,34 @@ To serialize or deserialize a type, needs This information is referred to as *metadata*. -## Metadata collection using source generation +## Metadata collection By default, `JsonSerializer` collects metadata at run time by using [Reflection](../../csharp/programming-guide/concepts/reflection.md). Whenever `JsonSerializer` has to serialize or deserialize a type for the first time, it collects and caches this metadata. The metadata collection process takes time and uses memory. You can use source generation to move the metadata collection process from run time to compile time. During compilation, the metadata is collected and source code files are generated. The generated source code files are automatically compiled as an integral part of the application. This compile-time metadata collection eliminates run-time metadata collection, which improves performance of both serialization and deserialization. -### Limitations of source generation metadata +## Source generation limitations and known issues -The following `JsonSerializer` features are not supported in metadata collection mode using source generation: +Source generation mode supports supports only `public` and `internal` accessors, and it doesn't support init-only properties. -| Feature -|------------------------------------------------------------------------| -| [Init-only properties](xref:System.Text.Json.Serialization.JsonIncludeAttribute) | -| [Private members](xref:System.Text.Json.Serialization.JsonIncludeAttribute) | +### public and internal accessors -The following table shows which attributes are supported by the optimized serialization code: +Reflection mode supports the use of non-`public` accessors for `public` properties. For example, you can apply [[JsonInclude]](xref:System.Text.Json.sSerialization.JsonIncludeAttribute) to a `private` setter or an `internal` getter. Source generation mode supports only `public` or `internal` accessors. Use of `[JsonInclude]` on non-`public` accessors in source generation mode results in a `NotSupportedException` at run time. -| Attribute | Supported by optimized code | -|-------------------------------------------------------------------|-----------------------------| -| | ❌ | -| | ❌ | -| | ✔️ | -| | ✔️ | -| | ❌ | -| | ✔️ | +In both reflection and source generation modes: + +* Only `public` properties and public fields are supported. +* Only `public` constructors can be used for deserialization. + +For information about the outstanding request to add support for non-public members, see GitHub issue [dotnet/runtime#31511](https://github.com/dotnet/runtime/issues/31511). Even if that request is implemented, source generation mode will still be limited to support for public members. + +### init-only properties + +Init-only prop deserialization is supported in the reflection serializer, but not source-gen. This is because the metadata-only mode required for deserialization cannot express the required initialization statically in source, while the reflection serializer can use runtime-reflection to set the properties after construction. + +### Known issues + +https://github.com/dotnet/runtime/issues?q=is%3Aopen+is%3Aissue+label%3Aarea-System.Text.Json+label%3Asource-generator ## Serialization optimization mode From cfbdd9608bc8b4ea2c3ff7946b0de7a5f3244e64 Mon Sep 17 00:00:00 2001 From: Tom Dykstra Date: Tue, 19 Oct 2021 14:49:46 -0700 Subject: [PATCH 05/11] draft --- ...ystem-text-json-source-generation-modes.md | 22 +++++++------------ 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/docs/standard/serialization/system-text-json-source-generation-modes.md b/docs/standard/serialization/system-text-json-source-generation-modes.md index fdb52c9f5d0cb..374f6fde49522 100644 --- a/docs/standard/serialization/system-text-json-source-generation-modes.md +++ b/docs/standard/serialization/system-text-json-source-generation-modes.md @@ -49,19 +49,17 @@ To serialize or deserialize a type, needs This information is referred to as *metadata*. -## Metadata collection - By default, `JsonSerializer` collects metadata at run time by using [Reflection](../../csharp/programming-guide/concepts/reflection.md). Whenever `JsonSerializer` has to serialize or deserialize a type for the first time, it collects and caches this metadata. The metadata collection process takes time and uses memory. -You can use source generation to move the metadata collection process from run time to compile time. During compilation, the metadata is collected and source code files are generated. The generated source code files are automatically compiled as an integral part of the application. This compile-time metadata collection eliminates run-time metadata collection, which improves performance of both serialization and deserialization. +## Source generation - metadata collection mode -## Source generation limitations and known issues +You can use source generation to move the metadata collection process from run time to compile time. During compilation, the metadata is collected and source code files are generated. The generated source code files are automatically compiled as an integral part of the application. This compile-time metadata collection eliminates run-time metadata collection, which improves performance of both serialization and deserialization. -Source generation mode supports supports only `public` and `internal` accessors, and it doesn't support init-only properties. +### Source generation limitations -### public and internal accessors +Reflection mode supports the use of non-public accessors for public properties. For example, you can apply [[JsonInclude]](xref:System.Text.Json.sSerialization.JsonIncludeAttribute) to a `private` setter or an `internal` getter. Source generation mode supports only `public` or `internal` accessors. Use of `[JsonInclude]` on non-`public` accessors in source generation mode results in a `NotSupportedException` at run time. -Reflection mode supports the use of non-`public` accessors for `public` properties. For example, you can apply [[JsonInclude]](xref:System.Text.Json.sSerialization.JsonIncludeAttribute) to a `private` setter or an `internal` getter. Source generation mode supports only `public` or `internal` accessors. Use of `[JsonInclude]` on non-`public` accessors in source generation mode results in a `NotSupportedException` at run time. +Source generation doesn't support deserialization to init-only properties. This is because the metadata-only mode required for deserialization can't express the required initialization statically in source code. The reflection serializer can use run-time reflection to set properties after construction. In both reflection and source generation modes: @@ -70,13 +68,7 @@ In both reflection and source generation modes: For information about the outstanding request to add support for non-public members, see GitHub issue [dotnet/runtime#31511](https://github.com/dotnet/runtime/issues/31511). Even if that request is implemented, source generation mode will still be limited to support for public members. -### init-only properties - -Init-only prop deserialization is supported in the reflection serializer, but not source-gen. This is because the metadata-only mode required for deserialization cannot express the required initialization statically in source, while the reflection serializer can use runtime-reflection to set the properties after construction. - -### Known issues - -https://github.com/dotnet/runtime/issues?q=is%3Aopen+is%3Aissue+label%3Aarea-System.Text.Json+label%3Asource-generator +For information about other known issues with source generation, see the [GitHub issues labeled `source-generator`](https://github.com/dotnet/runtime/issues?q=is%3Aopen+is%3Aissue+label%3Aarea-System.Text.Json+label%3Asource-generator) in the *dotnet/runtime* repository. ## Serialization optimization mode @@ -136,6 +128,8 @@ The performance improvements provided by source generation can be substantial. F The source generation functionality of System.Text.Json 6.0 and later can be used in any .NET C# project, including class libraries and console, web, and Blazor applications. You can use version 6.0 of System.Text.Json in projects that target earlier frameworks. For more information, see [How to get the library](system-text-json-overview.md#how-to-get-the-library). +## How to use source generation modes + For information about how to use source generation modes in code that uses System.Text.Json, see [How to use source generation in System.Text.Json](system-text-json-source-generation.md). :::zone-end From e9e8919e4199d8090f4976f7b2591cc15add7c47 Mon Sep 17 00:00:00 2001 From: Tom Dykstra Date: Tue, 19 Oct 2021 15:06:41 -0700 Subject: [PATCH 06/11] typo --- .../serialization/system-text-json-source-generation-modes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/standard/serialization/system-text-json-source-generation-modes.md b/docs/standard/serialization/system-text-json-source-generation-modes.md index 374f6fde49522..0a40c56ca96ca 100644 --- a/docs/standard/serialization/system-text-json-source-generation-modes.md +++ b/docs/standard/serialization/system-text-json-source-generation-modes.md @@ -57,7 +57,7 @@ You can use source generation to move the metadata collection process from run t ### Source generation limitations -Reflection mode supports the use of non-public accessors for public properties. For example, you can apply [[JsonInclude]](xref:System.Text.Json.sSerialization.JsonIncludeAttribute) to a `private` setter or an `internal` getter. Source generation mode supports only `public` or `internal` accessors. Use of `[JsonInclude]` on non-`public` accessors in source generation mode results in a `NotSupportedException` at run time. +Reflection mode supports the use of non-public accessors for public properties. For example, you can apply [[JsonInclude]](xref:System.Text.Json.Serialization.JsonIncludeAttribute) to a `private` setter or an `internal` getter. Source generation mode supports only `public` or `internal` accessors. Use of `[JsonInclude]` on non-`public` accessors in source generation mode results in a `NotSupportedException` at run time. Source generation doesn't support deserialization to init-only properties. This is because the metadata-only mode required for deserialization can't express the required initialization statically in source code. The reflection serializer can use run-time reflection to set properties after construction. From 1074c4a39122fa9f8b2073f1a8d8857defc77bd2 Mon Sep 17 00:00:00 2001 From: Tom Dykstra Date: Tue, 19 Oct 2021 16:22:57 -0700 Subject: [PATCH 07/11] draft --- ...ystem-text-json-source-generation-modes.md | 43 ++++++++----------- 1 file changed, 19 insertions(+), 24 deletions(-) diff --git a/docs/standard/serialization/system-text-json-source-generation-modes.md b/docs/standard/serialization/system-text-json-source-generation-modes.md index 0a40c56ca96ca..f0e1719710225 100644 --- a/docs/standard/serialization/system-text-json-source-generation-modes.md +++ b/docs/standard/serialization/system-text-json-source-generation-modes.md @@ -4,9 +4,6 @@ description: "Learn how to choose Reflection or source generation in System.Text ms.date: 10/18/2021 no-loc: [System.Text.Json] zone_pivot_groups: dotnet-version -dev_langs: - - "csharp" - - "vb" helpviewer_keywords: - "JSON serialization" - "serializing objects" @@ -21,18 +18,18 @@ ms.topic: how-to > [!IMPORTANT] > Some information relates to prerelease product that may be substantially modified before it's released. Microsoft makes no warranties, express or implied, with respect to the information provided here. -By default, `System.Text.Json` uses run-time Reflection to gather the metadata it needs to access properties of objects for serialization and deserialization. As an alternative, `System.Text.Json` can use the C# [source generation](../../csharp/roslyn-sdk/source-generators-overview.md) feature to improve performance, reduce private memory usage, and facilitate [assembly trimming](../../core/deploying/trimming/trim-self-contained.md), which reduces app size. +By default, `System.Text.Json` uses run-time Reflection to gather the metadata it needs to access properties of objects for serialization and deserialization. As an alternative, `System.Text.Json` 6.0 can use the C# [source generation](../../csharp/roslyn-sdk/source-generators-overview.md) feature to improve performance, reduce private memory usage, and facilitate [assembly trimming](../../core/deploying/trimming/trim-self-contained.md), which reduces app size. You can use version 6.0 of System.Text.Json in projects that target earlier frameworks. For more information, see [How to get the library](system-text-json-overview.md#how-to-get-the-library). -[The .NET 6.0 version of this article](system-text-json-source-generation-modes.md?pivots=dotnet-6-0) explains the options and gives guidance on how to choose the best approach for your scenario. +[The .NET 6.0 version of this article](system-text-json-source-generation-modes.md?pivots=dotnet-6-0) explains the options and provides guidance on how to choose the best approach for your scenario. :::zone-end :::zone pivot="dotnet-5-0,dotnet-core-3-1" [System.Text.Json](system-text-json-overview.md) version 6.0 and later can use the C# [source generation](../../csharp/roslyn-sdk/source-generators-overview.md) feature to improve performance, reduce private memory usage, and improve [assembly trimming](../../core/deploying/trimming/trim-self-contained.md) accuracy. You can use version 6.0 of System.Text.Json in projects that target earlier frameworks. For more information, see: -* [The .NET 6.0 version of this article](system-text-json-source-generation-modes.md?pivots=dotnet-6-0). * [How to get the library](system-text-json-overview.md#how-to-get-the-library) +* [The .NET 6.0 version of this article](system-text-json-source-generation-modes.md?pivots=dotnet-6-0). :::zone-end @@ -44,7 +41,7 @@ To serialize or deserialize a type, needs * How to access property getters and fields for serialization. * How to access a constructor, property setters, and fields for deserialization. -* Attributes that have been used to customize serialization or deserialization. +* Information about which attributes have been used to customize serialization or deserialization. * Run-time configuration from . This information is referred to as *metadata*. @@ -55,11 +52,11 @@ By default, `JsonSerializer` collects metadata at run time by using [Reflection] You can use source generation to move the metadata collection process from run time to compile time. During compilation, the metadata is collected and source code files are generated. The generated source code files are automatically compiled as an integral part of the application. This compile-time metadata collection eliminates run-time metadata collection, which improves performance of both serialization and deserialization. -### Source generation limitations +## Source generation - known issues -Reflection mode supports the use of non-public accessors for public properties. For example, you can apply [[JsonInclude]](xref:System.Text.Json.Serialization.JsonIncludeAttribute) to a `private` setter or an `internal` getter. Source generation mode supports only `public` or `internal` accessors. Use of `[JsonInclude]` on non-`public` accessors in source generation mode results in a `NotSupportedException` at run time. +Reflection mode supports the use of non-public accessors of public properties. For example, you can apply [[JsonInclude]](xref:System.Text.Json.Serialization.JsonIncludeAttribute) to a property that has a `private` setter or getter. Source generation mode supports only public or internal accessors of public properties. Use of `[JsonInclude]` on non-public accessors in source generation mode results in a `NotSupportedException` at run time. -Source generation doesn't support deserialization to init-only properties. This is because the metadata-only mode required for deserialization can't express the required initialization statically in source code. The reflection serializer can use run-time reflection to set properties after construction. +Reflection mode also supports deserialization to init-only properties. Source generation doesn't support this, because the metadata-only mode required for deserialization can't express the required initialization statically in source code. The reflection serializer uses run-time reflection to set properties after construction. In both reflection and source generation modes: @@ -110,27 +107,25 @@ If a non-supported option or attribute is specified for a type, the serializer f Choose Reflection or source generation modes based on the following benefits that each one offers: -| Benefit | Reflection | Metadata collection | Serialization optimization | -|-------------------------------------------|------------|---------------------|----------------------------| -| Simpler to code and debug. | ✔️ | ❌ | ❌ | -| Supports all available options. | ✔️ | ❌ | ❌ | -| Reduces start-up time. | ❌ | ✔️ | ❌ | -| Reduces private memory usage. | ❌ | ✔️ | ✔️ | -| Eliminates run-time reflection. | ❌ | ✔️ | ✔️ | -| Facilitates trim-safe app size reduction. | ❌ | ✔️ | ✔️ | -| Increases serialization throughput. | ❌ | ❌ | ✔️ \* | +| Benefit | Reflection | Metadata collection | Serialization optimization | +|------------------------------------------------------|------------|---------------------|----------------------------| +| Simpler to code and debug. | ✔️ | ❌ | ❌ | +| Supports non-public accessors. | ✔️ | ❌ | ❌ | +| Supports init-only properties. | ✔️ | ❌ | ❌ | +| Supports all available serialization customizations. | ✔️ | ❌ | ❌ | +| Reduces start-up time. | ❌ | ✔️ | ❌ | +| Reduces private memory usage. | ❌ | ✔️ | ✔️ | +| Eliminates run-time reflection. | ❌ | ✔️ | ✔️ | +| Facilitates trim-safe app size reduction. | ❌ | ✔️ | ✔️ | +| Increases serialization throughput. | ❌ | ❌ | ✔️ \* | The performance improvements provided by source generation can be substantial. For example, [test results](https://devblogs.microsoft.com/dotnet/try-the-new-system-text-json-source-generator/#how-source-generation-provides-benefits) have shown up to 40% or more startup time reduction, private memory reduction, throughput speed increase, and app size reduction. \* As explained in the [preceding section](#serialization-optimization-mode), the optimized code doesn't support some features. Do performance testing with your options and workloads to determine how much benefit you can actually get from serialization optimization mode. Also, the ability to fall back to `JsonSerializer` code requires metadata collection mode. If you select only serialization optimization mode, serialization might fail for types or options that need to fall back to `JsonSerializer` code. -## Get the source generation functionality - -The source generation functionality of System.Text.Json 6.0 and later can be used in any .NET C# project, including class libraries and console, web, and Blazor applications. You can use version 6.0 of System.Text.Json in projects that target earlier frameworks. For more information, see [How to get the library](system-text-json-overview.md#how-to-get-the-library). - ## How to use source generation modes -For information about how to use source generation modes in code that uses System.Text.Json, see [How to use source generation in System.Text.Json](system-text-json-source-generation.md). +Most of the System.Text.Json documentation shows how to write code that uses Reflection mode. For information about how to use source generation modes, see [How to use source generation in System.Text.Json](system-text-json-source-generation.md). :::zone-end ## See also From 45554a6ee965f06f6461c651b1dd83a107e49c16 Mon Sep 17 00:00:00 2001 From: Tom Dykstra Date: Wed, 20 Oct 2021 08:56:54 -0700 Subject: [PATCH 08/11] corrections --- docs/standard/serialization/system-text-json-overview.md | 6 ++---- .../system-text-json-source-generation-modes.md | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/docs/standard/serialization/system-text-json-overview.md b/docs/standard/serialization/system-text-json-overview.md index a287251534753..26305073874cc 100644 --- a/docs/standard/serialization/system-text-json-overview.md +++ b/docs/standard/serialization/system-text-json-overview.md @@ -23,11 +23,11 @@ There are some limitations on what parts of the library that you can use from Vi ## Run-time Reflection vs. compile-time source generation -By default, `System.Text.Json` uses run-time [Reflection](../../csharp/programming-guide/concepts/reflection.md) to gather the metadata it needs to access properties of objects for serialization and deserialization. As an alternative, `System.Text.Json` can use the C# [source generation](../../csharp/roslyn-sdk/source-generators-overview.md) feature to improve performance, reduce private memory usage, and facilitate [assembly trimming](../../core/deploying/trimming/trim-self-contained.md), which reduces app size. For information about how to choose between Reflection and source generation, see [Source generation modes in System.Text.Json](system-text-json-source-generation-modes.md). +By default, `System.Text.Json` uses run-time [Reflection](../../csharp/programming-guide/concepts/reflection.md) to gather the metadata it needs to access properties of objects for serialization and deserialization. As an alternative, `System.Text.Json` can use the C# [source generation](../../csharp/roslyn-sdk/source-generators-overview.md) feature to improve performance, reduce private memory usage, and facilitate [assembly trimming](../../core/deploying/trimming/trim-self-contained.md), which reduces app size. For more information, see [How to choose Reflection or source generation in System.Text.Json](system-text-json-source-generation-modes.md). ## How to get the library -The library is built-in as part of the shared framework for .NET Core 3.0 and later versions. The source generation modes are built-in as part of the shared framework for .NET 6.0 and later versions. +The library is built-in as part of the shared framework for .NET Core 3.0 and later versions. The source generation feature is built-in as part of the shared framework for .NET 6.0 and later versions. Use of source generation requires .NET 5 SDK or later. For framework versions earlier than .NET Core 3.0, install the [System.Text.Json](https://www.nuget.org/packages/System.Text.Json) NuGet package. The package supports: @@ -36,8 +36,6 @@ For framework versions earlier than .NET Core 3.0, install the [System.Text.Json * .NET Core 2.1 and later * .NET 5 and later -Use of the Source generation features requires System.Text.Json 6.0 or later and .NET 5 SDK or later. - ## Security information For information about security threats that were considered when designing , and how they can be mitigated, see [`System.Text.Json` Threat Model](https://github.com/dotnet/runtime/blob/main/src/libraries/System.Text.Json/docs/ThreatModel.md). diff --git a/docs/standard/serialization/system-text-json-source-generation-modes.md b/docs/standard/serialization/system-text-json-source-generation-modes.md index f0e1719710225..d524bc3c1f7bd 100644 --- a/docs/standard/serialization/system-text-json-source-generation-modes.md +++ b/docs/standard/serialization/system-text-json-source-generation-modes.md @@ -22,7 +22,7 @@ By default, `System.Text.Json` uses run-time Reflection to gather the metadata i You can use version 6.0 of System.Text.Json in projects that target earlier frameworks. For more information, see [How to get the library](system-text-json-overview.md#how-to-get-the-library). -[The .NET 6.0 version of this article](system-text-json-source-generation-modes.md?pivots=dotnet-6-0) explains the options and provides guidance on how to choose the best approach for your scenario. +This article explains the options and provides guidance on how to choose the best approach for your scenario. :::zone-end :::zone pivot="dotnet-5-0,dotnet-core-3-1" From e9a5fa12643e658719146b02184fc2418d5eaed3 Mon Sep 17 00:00:00 2001 From: Tom Dykstra Date: Wed, 20 Oct 2021 13:45:02 -0700 Subject: [PATCH 09/11] address feedback --- docs/fundamentals/toc.yml | 2 +- ...ystem-text-json-source-generation-modes.md | 60 +++++++++---------- 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/docs/fundamentals/toc.yml b/docs/fundamentals/toc.yml index e6fd15e873119..300f2a5224c2d 100644 --- a/docs/fundamentals/toc.yml +++ b/docs/fundamentals/toc.yml @@ -2009,7 +2009,7 @@ items: href: ../standard/serialization/system-text-json-overview.md displayName: json serialization - name: Reflection vs. source generation - href: ../standard/serialization/system-text-json-source-generation.md + href: ../standard/serialization/system-text-json-source-generation-modes.md - name: How to serialize and deserialize JSON href: ../standard/serialization/system-text-json-how-to.md - name: Control serialization behavior diff --git a/docs/standard/serialization/system-text-json-source-generation-modes.md b/docs/standard/serialization/system-text-json-source-generation-modes.md index d524bc3c1f7bd..9efd2bfeccd53 100644 --- a/docs/standard/serialization/system-text-json-source-generation-modes.md +++ b/docs/standard/serialization/system-text-json-source-generation-modes.md @@ -1,6 +1,6 @@ --- -title: How to choose Reflection or source generation in System.Text.Json -description: "Learn how to choose Reflection or source generation in System.Text.Json." +title: How to choose reflection or source generation in System.Text.Json +description: "Learn how to choose reflection or source generation in System.Text.Json." ms.date: 10/18/2021 no-loc: [System.Text.Json] zone_pivot_groups: dotnet-version @@ -12,13 +12,13 @@ helpviewer_keywords: ms.topic: how-to --- -# How to choose Reflection or source generation in System.Text.Json +# How to choose reflection or source generation in System.Text.Json :::zone pivot="dotnet-6-0" > [!IMPORTANT] > Some information relates to prerelease product that may be substantially modified before it's released. Microsoft makes no warranties, express or implied, with respect to the information provided here. -By default, `System.Text.Json` uses run-time Reflection to gather the metadata it needs to access properties of objects for serialization and deserialization. As an alternative, `System.Text.Json` 6.0 can use the C# [source generation](../../csharp/roslyn-sdk/source-generators-overview.md) feature to improve performance, reduce private memory usage, and facilitate [assembly trimming](../../core/deploying/trimming/trim-self-contained.md), which reduces app size. +By default, `System.Text.Json` uses run-time reflection to gather the metadata it needs to access properties of objects for serialization and deserialization. As an alternative, `System.Text.Json` 6.0 can use the C# [source generation](../../csharp/roslyn-sdk/source-generators-overview.md) feature to improve performance, reduce private memory usage, and facilitate [assembly trimming](../../core/deploying/trimming/trim-self-contained.md), which reduces app size. You can use version 6.0 of System.Text.Json in projects that target earlier frameworks. For more information, see [How to get the library](system-text-json-overview.md#how-to-get-the-library). @@ -35,6 +35,24 @@ This article explains the options and provides guidance on how to choose the bes :::zone pivot="dotnet-6-0" +## Overview + +Choose reflection or source generation modes based on the following benefits that each one offers: + +| Benefit | Reflection | Metadata collection | Serialization optimization | +|------------------------------------------------------|------------|---------------------|----------------------------| +| Simpler to code and debug. | ✔️ | ❌ | ❌ | +| Supports non-public accessors. | ✔️ | ❌ | ❌ | +| Supports init-only properties. | ✔️ | ❌ | ❌ | +| Supports all available serialization customizations. | ✔️ | ❌ | ❌ | +| Reduces start-up time. | ❌ | ✔️ | ❌ | +| Reduces private memory usage. | ❌ | ✔️ | ✔️ | +| Eliminates run-time reflection. | ❌ | ✔️ | ✔️ | +| Facilitates trim-safe app size reduction. | ❌ | ✔️ | ✔️ | +| Increases serialization throughput. | ❌ | ❌ | ✔️ | + +The following sections explain these options and their relative benefits. + ## System.Text.Json metadata To serialize or deserialize a type, needs information about how to access the members of the type. `JsonSerializer` needs the following information: @@ -46,12 +64,14 @@ To serialize or deserialize a type, needs This information is referred to as *metadata*. -By default, `JsonSerializer` collects metadata at run time by using [Reflection](../../csharp/programming-guide/concepts/reflection.md). Whenever `JsonSerializer` has to serialize or deserialize a type for the first time, it collects and caches this metadata. The metadata collection process takes time and uses memory. +By default, `JsonSerializer` collects metadata at run time by using [reflection](../../csharp/programming-guide/concepts/reflection.md). Whenever `JsonSerializer` has to serialize or deserialize a type for the first time, it collects and caches this metadata. The metadata collection process takes time and uses memory. ## Source generation - metadata collection mode You can use source generation to move the metadata collection process from run time to compile time. During compilation, the metadata is collected and source code files are generated. The generated source code files are automatically compiled as an integral part of the application. This compile-time metadata collection eliminates run-time metadata collection, which improves performance of both serialization and deserialization. +The performance improvements provided by source generation can be substantial. For example, [test results](https://devblogs.microsoft.com/dotnet/try-the-new-system-text-json-source-generator/#how-source-generation-provides-benefits) have shown up to 40% or more startup time reduction, private memory reduction, throughput speed increase (in serialization optimization mode), and app size reduction. + ## Source generation - known issues Reflection mode supports the use of non-public accessors of public properties. For example, you can apply [[JsonInclude]](xref:System.Text.Json.Serialization.JsonIncludeAttribute) to a property that has a `private` setter or getter. Source generation mode supports only public or internal accessors of public properties. Use of `[JsonInclude]` on non-public accessors in source generation mode results in a `NotSupportedException` at run time. @@ -60,12 +80,12 @@ Reflection mode also supports deserialization to init-only properties. Source ge In both reflection and source generation modes: -* Only `public` properties and public fields are supported. -* Only `public` constructors can be used for deserialization. +* Only public properties and public fields are supported. +* Only public constructors can be used for deserialization. For information about the outstanding request to add support for non-public members, see GitHub issue [dotnet/runtime#31511](https://github.com/dotnet/runtime/issues/31511). Even if that request is implemented, source generation mode will still be limited to support for public members. -For information about other known issues with source generation, see the [GitHub issues labeled `source-generator`](https://github.com/dotnet/runtime/issues?q=is%3Aopen+is%3Aissue+label%3Aarea-System.Text.Json+label%3Asource-generator) in the *dotnet/runtime* repository. +For information about other known issues with source generation, see the [GitHub issues that are labeled "source-generator"](https://github.com/dotnet/runtime/issues?q=is%3Aopen+is%3Aissue+label%3Aarea-System.Text.Json+label%3Asource-generator) in the *dotnet/runtime* repository. ## Serialization optimization mode @@ -101,31 +121,11 @@ The following table shows which attributes are supported by the optimized serial | | ❌ | | | ✔️ | -If a non-supported option or attribute is specified for a type, the serializer falls back to the default `JsonSerializer` code. In that case the optimized code isn't used when serializing that type but may be used for other types. - -## Choose Reflection or a source generation mode - -Choose Reflection or source generation modes based on the following benefits that each one offers: - -| Benefit | Reflection | Metadata collection | Serialization optimization | -|------------------------------------------------------|------------|---------------------|----------------------------| -| Simpler to code and debug. | ✔️ | ❌ | ❌ | -| Supports non-public accessors. | ✔️ | ❌ | ❌ | -| Supports init-only properties. | ✔️ | ❌ | ❌ | -| Supports all available serialization customizations. | ✔️ | ❌ | ❌ | -| Reduces start-up time. | ❌ | ✔️ | ❌ | -| Reduces private memory usage. | ❌ | ✔️ | ✔️ | -| Eliminates run-time reflection. | ❌ | ✔️ | ✔️ | -| Facilitates trim-safe app size reduction. | ❌ | ✔️ | ✔️ | -| Increases serialization throughput. | ❌ | ❌ | ✔️ \* | - -The performance improvements provided by source generation can be substantial. For example, [test results](https://devblogs.microsoft.com/dotnet/try-the-new-system-text-json-source-generator/#how-source-generation-provides-benefits) have shown up to 40% or more startup time reduction, private memory reduction, throughput speed increase, and app size reduction. - -\* As explained in the [preceding section](#serialization-optimization-mode), the optimized code doesn't support some features. Do performance testing with your options and workloads to determine how much benefit you can actually get from serialization optimization mode. Also, the ability to fall back to `JsonSerializer` code requires metadata collection mode. If you select only serialization optimization mode, serialization might fail for types or options that need to fall back to `JsonSerializer` code. +If a non-supported option or attribute is specified for a type, the serializer falls back to the default `JsonSerializer` code. In that case, the optimized code isn't used when serializing that type but may be used for other types. Therefore it's important to do performance testing with your options and workloads to determine how much benefit you can actually get from serialization optimization mode. Also, the ability to fall back to `JsonSerializer` code requires metadata collection mode. If you select only serialization optimization mode, serialization might fail for types or options that need to fall back to `JsonSerializer` code. ## How to use source generation modes -Most of the System.Text.Json documentation shows how to write code that uses Reflection mode. For information about how to use source generation modes, see [How to use source generation in System.Text.Json](system-text-json-source-generation.md). +Most of the System.Text.Json documentation shows how to write code that uses reflection mode. For information about how to use source generation modes, see [How to use source generation in System.Text.Json](system-text-json-source-generation.md). :::zone-end ## See also From 9f06a84b84edb95b608e9181fc7e84dff96ec587 Mon Sep 17 00:00:00 2001 From: Tom Dykstra Date: Wed, 20 Oct 2021 15:27:41 -0700 Subject: [PATCH 10/11] fix capitalization --- docs/standard/serialization/system-text-json-overview.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/standard/serialization/system-text-json-overview.md b/docs/standard/serialization/system-text-json-overview.md index 26305073874cc..697333261bb7b 100644 --- a/docs/standard/serialization/system-text-json-overview.md +++ b/docs/standard/serialization/system-text-json-overview.md @@ -21,9 +21,9 @@ The library also provides classes for working with an in-memory document object There are some limitations on what parts of the library that you can use from Visual Basic code. For more information, see [Visual Basic support](system-text-json-how-to.md#visual-basic-support). -## Run-time Reflection vs. compile-time source generation +## Run-time reflection vs. compile-time source generation -By default, `System.Text.Json` uses run-time [Reflection](../../csharp/programming-guide/concepts/reflection.md) to gather the metadata it needs to access properties of objects for serialization and deserialization. As an alternative, `System.Text.Json` can use the C# [source generation](../../csharp/roslyn-sdk/source-generators-overview.md) feature to improve performance, reduce private memory usage, and facilitate [assembly trimming](../../core/deploying/trimming/trim-self-contained.md), which reduces app size. For more information, see [How to choose Reflection or source generation in System.Text.Json](system-text-json-source-generation-modes.md). +By default, `System.Text.Json` uses run-time [reflection](../../csharp/programming-guide/concepts/reflection.md) to gather the metadata it needs to access properties of objects for serialization and deserialization. As an alternative, `System.Text.Json` can use the C# [source generation](../../csharp/roslyn-sdk/source-generators-overview.md) feature to improve performance, reduce private memory usage, and facilitate [assembly trimming](../../core/deploying/trimming/trim-self-contained.md), which reduces app size. For more information, see [How to choose reflection or source generation in System.Text.Json](system-text-json-source-generation-modes.md). ## How to get the library From 4ce055e0d1934ff4d06d8fe290d9d70a95cb129b Mon Sep 17 00:00:00 2001 From: Tom Dykstra Date: Thu, 21 Oct 2021 08:54:09 -0700 Subject: [PATCH 11/11] Update docs/standard/serialization/system-text-json-source-generation-modes.md Co-authored-by: Genevieve Warren <24882762+gewarren@users.noreply.github.com> --- .../serialization/system-text-json-source-generation-modes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/standard/serialization/system-text-json-source-generation-modes.md b/docs/standard/serialization/system-text-json-source-generation-modes.md index 9efd2bfeccd53..35d0a52e0ed43 100644 --- a/docs/standard/serialization/system-text-json-source-generation-modes.md +++ b/docs/standard/serialization/system-text-json-source-generation-modes.md @@ -39,7 +39,7 @@ This article explains the options and provides guidance on how to choose the bes Choose reflection or source generation modes based on the following benefits that each one offers: -| Benefit | Reflection | Metadata collection | Serialization optimization | +| Benefit | Reflection | Source generation:
Metadata collection | Source generation:
Serialization optimization | |------------------------------------------------------|------------|---------------------|----------------------------| | Simpler to code and debug. | ✔️ | ❌ | ❌ | | Supports non-public accessors. | ✔️ | ❌ | ❌ |