Skip to content

Commit 2a8103b

Browse files
authored
Add System.Text.Json polymorphic serialization support to TypedComponent (#1554)
This change adds support for `System.Text.Json` serialization while maintaining backward compatibility with `Newtonsoft.Json`. `TypedComponent` and its derived types can now be serialized/deserialized with either JSON library. This enables gradual migration from `Newtonsoft.Json` to `System.Text.Json` without breaking existing serialization code or changing JSON output format. Related to #231
1 parent de180e0 commit 2a8103b

File tree

1 file changed

+29
-3
lines changed

1 file changed

+29
-3
lines changed

src/Microsoft.ComponentDetection.Contracts/TypedComponent/TypedComponent.cs

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,42 @@ namespace Microsoft.ComponentDetection.Contracts.TypedComponent;
44
using System;
55
using System.Collections.Generic;
66
using System.Diagnostics;
7+
using System.Text.Json.Serialization;
78
using Microsoft.ComponentDetection.Contracts.BcdeModels;
89
using Newtonsoft.Json;
910
using Newtonsoft.Json.Converters;
1011
using Newtonsoft.Json.Serialization;
1112
using PackageUrl;
13+
using JsonConverterAttribute = Newtonsoft.Json.JsonConverterAttribute;
14+
using JsonIgnoreAttribute = Newtonsoft.Json.JsonIgnoreAttribute;
1215

1316
[JsonObject(MemberSerialization.OptOut, NamingStrategyType = typeof(CamelCaseNamingStrategy))]
1417
[JsonConverter(typeof(TypedComponentConverter))]
1518
[DebuggerDisplay("{DebuggerDisplay,nq}")]
19+
[JsonPolymorphic(TypeDiscriminatorPropertyName = "type")]
20+
[JsonDerivedType(typeof(CargoComponent), typeDiscriminator: nameof(ComponentType.Cargo))]
21+
[JsonDerivedType(typeof(ConanComponent), typeDiscriminator: nameof(ComponentType.Conan))]
22+
[JsonDerivedType(typeof(CondaComponent), typeDiscriminator: nameof(ComponentType.Conda))]
23+
[JsonDerivedType(typeof(DockerImageComponent), typeDiscriminator: nameof(ComponentType.DockerImage))]
24+
[JsonDerivedType(typeof(DockerReferenceComponent), typeDiscriminator: nameof(ComponentType.DockerReference))]
25+
[JsonDerivedType(typeof(DotNetComponent), typeDiscriminator: nameof(ComponentType.DotNet))]
26+
[JsonDerivedType(typeof(GitComponent), typeDiscriminator: nameof(ComponentType.Git))]
27+
[JsonDerivedType(typeof(GoComponent), typeDiscriminator: nameof(ComponentType.Go))]
28+
[JsonDerivedType(typeof(LinuxComponent), typeDiscriminator: nameof(ComponentType.Linux))]
29+
[JsonDerivedType(typeof(MavenComponent), typeDiscriminator: nameof(ComponentType.Maven))]
30+
[JsonDerivedType(typeof(NpmComponent), typeDiscriminator: nameof(ComponentType.Npm))]
31+
[JsonDerivedType(typeof(NuGetComponent), typeDiscriminator: nameof(ComponentType.NuGet))]
32+
[JsonDerivedType(typeof(OtherComponent), typeDiscriminator: nameof(ComponentType.Other))]
33+
[JsonDerivedType(typeof(PipComponent), typeDiscriminator: nameof(ComponentType.Pip))]
34+
[JsonDerivedType(typeof(PodComponent), typeDiscriminator: nameof(ComponentType.Pod))]
35+
[JsonDerivedType(typeof(RubyGemsComponent), typeDiscriminator: nameof(ComponentType.RubyGems))]
36+
[JsonDerivedType(typeof(SpdxComponent), typeDiscriminator: nameof(ComponentType.Spdx))]
37+
[JsonDerivedType(typeof(SwiftComponent), typeDiscriminator: nameof(ComponentType.Swift))]
38+
[JsonDerivedType(typeof(VcpkgComponent), typeDiscriminator: nameof(ComponentType.Vcpkg))]
1639
public abstract class TypedComponent
1740
{
18-
[JsonIgnore]
41+
[JsonIgnore] // Newtonsoft.Json
42+
[System.Text.Json.Serialization.JsonIgnore] // System.Text.Json
1943
private string id;
2044

2145
internal TypedComponent()
@@ -24,15 +48,17 @@ internal TypedComponent()
2448
}
2549

2650
/// <summary>Gets the type of the component, must be well known.</summary>
27-
[JsonConverter(typeof(StringEnumConverter))]
51+
[JsonConverter(typeof(StringEnumConverter))] // Newtonsoft.Json
52+
[System.Text.Json.Serialization.JsonConverter(typeof(JsonStringEnumConverter))] // System.Text.Json
2853
public abstract ComponentType Type { get; }
2954

3055
/// <summary>Gets the id of the component.</summary>
3156
public string Id => this.id ??= this.ComputeId();
3257

3358
public virtual PackageURL PackageUrl { get; }
3459

35-
[JsonIgnore]
60+
[JsonIgnore] // Newtonsoft.Json
61+
[System.Text.Json.Serialization.JsonIgnore] // System.Text.Json
3662
internal string DebuggerDisplay => $"{this.Id}";
3763

3864
protected string ValidateRequiredInput(string input, string fieldName, string componentType)

0 commit comments

Comments
 (0)