Skip to content

Commit

Permalink
Add support for STJ-native C# code gen
Browse files Browse the repository at this point in the history
  • Loading branch information
schnerring committed Feb 13, 2024
1 parent 3585d60 commit ee1b983
Show file tree
Hide file tree
Showing 9 changed files with 86 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -80,5 +80,27 @@ public async Task When_schema_has_base_schema_then_it_is_referenced_with_STJ()
Assert.Contains("[JsonInheritanceAttribute(\"Banana\", typeof(Banana))]", code);
Assert.Contains("public class JsonInheritanceConverter<TBase> : System.Text.Json.Serialization.JsonConverter<TBase>", code);
}

[Fact]
public async Task When_using_STJ_polymorphic_serialization_then_NSwag_inheritance_converter_and_attributes_are_not_generated()
{
//// Arrange
var json = JsonSchema.FromType<MyContainer>();
var data = json.ToJson();

var generator = new CSharpGenerator(json, new CSharpGeneratorSettings
{
JsonLibrary = CSharpJsonLibrary.SystemTextJson,
JsonPolymorphicSerializationStyle = CSharpJsonPolymorphicSerializationStyle.SystemTextJson
});

//// Act
var code = generator.GenerateFile();

//// Assert
Assert.DoesNotContain("[JsonInheritanceConverter", code);
Assert.DoesNotContain("[JsonInheritanceAttribute", code);
Assert.DoesNotContain("public class JsonInheritanceConverter", code);
}
}
}
27 changes: 27 additions & 0 deletions src/NJsonSchema.CodeGeneration.CSharp.Tests/InheritanceTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,33 @@ public async Task When_definitions_inherit_from_root_schema()
Assert.Contains("[JsonInheritanceAttribute(\"PersianCat\", typeof(PersianCat))]", code);
}

[Fact]
public async Task When_definitions_inherit_from_root_schema_and_STJ_polymorphism()
{
//// Arrange
var path = GetTestDirectory() + "/References/Animal.json";

//// Act
var schema = await JsonSchema.FromFileAsync(path);
var generator = new CSharpGenerator(schema, new CSharpGeneratorSettings
{
ClassStyle = CSharpClassStyle.Record,
JsonLibrary = CSharpJsonLibrary.SystemTextJson,
JsonPolymorphicSerializationStyle = CSharpJsonPolymorphicSerializationStyle.SystemTextJson
});

//// Act
var code = generator.GenerateFile();

//// Assert
Assert.Contains("public abstract partial class Animal", code);
Assert.Contains("public partial class Cat : Animal", code);
Assert.Contains("public partial class PersianCat : Cat", code);
Assert.Contains("[System.Text.Json.Serialization.JsonPolymorphic(TypeDiscriminatorPropertyName = \"discriminator\")]", code);
Assert.Contains("[System.Text.Json.Serialization.JsonDerivedType(typeof(Cat), typeDiscriminator: \"Cat\")]", code);
Assert.Contains("[System.Text.Json.Serialization.JsonDerivedType(typeof(PersianCat), typeDiscriminator: \"PersianCat\")]", code);
}

private string GetTestDirectory()
{
var codeBase = Assembly.GetExecutingAssembly().CodeBase;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public CSharpGeneratorSettings()

ClassStyle = CSharpClassStyle.Poco;
JsonLibrary = CSharpJsonLibrary.NewtonsoftJson;
JsonPolymorphicSerializationStyle = CSharpJsonPolymorphicSerializationStyle.NSwag;

RequiredPropertiesMustBeDefined = true;
GenerateDataAnnotations = true;
Expand Down Expand Up @@ -120,6 +121,9 @@ public CSharpGeneratorSettings()
/// <summary>Gets or sets the CSharp JSON library to use (default: 'NewtonsoftJson', 'SystemTextJson' is experimental/not complete).</summary>
public CSharpJsonLibrary JsonLibrary { get; set; }

/// <summary>Gets or sets the CSharp JSON polymorphic serialization style (default: 'NSwag', 'SystemTextJson' is experimental/not complete).</summary>
public CSharpJsonPolymorphicSerializationStyle JsonPolymorphicSerializationStyle { get; set; }

/// <summary>Gets or sets the access modifier of generated classes and interfaces (default: 'public').</summary>
public string TypeAccessModifier { get; set; }

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
namespace NJsonSchema.CodeGeneration.CSharp
{
/// <summary>The CSharp JSON polymorphic serialization style.</summary>
public enum CSharpJsonPolymorphicSerializationStyle
{
/// <summary>Use NSwag polymorphic serialization</summary>
NSwag,

/// <summary>Use System.Text.Json polymorphic serialization</summary>
SystemTextJson
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ public ClassTemplateModel(string typeName, CSharpGeneratorSettings settings,
/// <summary>Gets a value indicating whether to use System.Text.Json</summary>
public bool UseSystemTextJson => _settings.JsonLibrary == CSharpJsonLibrary.SystemTextJson;

/// <summary>Gets a value indicating whether to use System.Text.Json polymorphic serialization</summary>
public bool UseSystemTextJsonPolymorphicSerialization => _settings.JsonPolymorphicSerializationStyle == CSharpJsonPolymorphicSerializationStyle.SystemTextJson;

/// <summary>Gets or sets the class name.</summary>
public override string ClassName { get; }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,8 @@ public JsonInheritanceConverterTemplateModel(CSharpGeneratorSettings settings)

/// <summary>Gets a value indicating whether to use System.Text.Json</summary>
public bool UseSystemTextJson => _settings.JsonLibrary == CSharpJsonLibrary.SystemTextJson;

/// <summary>Gets a value indicating whether to use System.Text.Json polymorphic serialization</summary>
public bool UseSystemTextJsonPolymorphicSerialization => _settings.JsonPolymorphicSerializationStyle == CSharpJsonPolymorphicSerializationStyle.SystemTextJson;
}
}
8 changes: 8 additions & 0 deletions src/NJsonSchema.CodeGeneration.CSharp/Templates/Class.liquid
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,22 @@
{%- endif -%}
{%- if HasDiscriminator -%}
{%- if UseSystemTextJson -%}
{%- if UseSystemTextJsonPolymorphicSerialization -%}
[System.Text.Json.Serialization.JsonPolymorphic(TypeDiscriminatorPropertyName = "{{ Discriminator }}")]
{%- else -%}
[JsonInheritanceConverter(typeof({{ ClassName }}), "{{ Discriminator }}")]
{%- endif -%}
{%- else -%}
[Newtonsoft.Json.JsonConverter(typeof(JsonInheritanceConverter), "{{ Discriminator }}")]
{%- endif -%}
{%- for derivedClass in DerivedClasses -%}
{%- if derivedClass.IsAbstract != true -%}
{%- if UseSystemTextJson and UseSystemTextJsonPolymorphicSerialization -%}
[System.Text.Json.Serialization.JsonDerivedType(typeof({{ derivedClass.ClassName }}), typeDiscriminator: "{{ derivedClass.Discriminator }}")]
{%- else -%}
[JsonInheritanceAttribute("{{ derivedClass.Discriminator }}", typeof({{ derivedClass.ClassName }}))]
{%- endif -%}
{%- endif -%}
{%- endfor -%}
{%- endif -%}
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "{{ ToolchainVersion }}")]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "{{ ToolchainVersion }}")]
{%- if UseSystemTextJsonPolymorphicSerialization == false -%}
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "{{ ToolchainVersion }}")]
[System.AttributeUsage(System.AttributeTargets.Class | System.AttributeTargets.Interface, AllowMultiple = true)]
internal class JsonInheritanceAttribute : System.Attribute
{
Expand All @@ -11,4 +12,5 @@ internal class JsonInheritanceAttribute : System.Attribute
public string Key { get; }

public System.Type Type { get; }
}
}
{%- endif -%}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "{{ ToolchainVersion }}")]
{%- if UseSystemTextJsonPolymorphicSerialization == false -%}
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "{{ ToolchainVersion }}")]
{%- if UseSystemTextJson -%}
internal class JsonInheritanceConverterAttribute : System.Text.Json.Serialization.JsonConverterAttribute
{
Expand Down Expand Up @@ -236,3 +237,4 @@ public class JsonInheritanceConverter : Newtonsoft.Json.JsonConverter
}
}
{%- endif -%}
{%- endif -%}

0 comments on commit ee1b983

Please sign in to comment.