diff --git a/src/.editorconfig b/src/.editorconfig new file mode 100644 index 000000000..aaad355eb --- /dev/null +++ b/src/.editorconfig @@ -0,0 +1,10 @@ +; What is EditorConfig? http://editorconfig.org/ + +root = true + +; general settings +[*] +indent_style = space +indent_size = 4 +end_of_line = crlf +insert_final_newline = false diff --git a/src/NJsonSchema.CodeGeneration.CSharp.Tests/CSharpGeneratorTests.cs b/src/NJsonSchema.CodeGeneration.CSharp.Tests/CSharpGeneratorTests.cs index 296522b2f..e61f2ad01 100644 --- a/src/NJsonSchema.CodeGeneration.CSharp.Tests/CSharpGeneratorTests.cs +++ b/src/NJsonSchema.CodeGeneration.CSharp.Tests/CSharpGeneratorTests.cs @@ -1401,5 +1401,58 @@ public async Task When_definition_contains_datetime_converter_should_not_be_adde Assert.DoesNotContain(@"class DateFormatConverter", code); Assert.DoesNotContain(@"[Newtonsoft.Json.JsonConverter(typeof(DateFormatConverter))]", code); } + + [Fact] + public async Task When_record_no_setter_in_class_and_constructor_provided() + { + //// Arrange + var schema = await JsonSchema4.FromTypeAsync
(); + var data = schema.ToJson(); + var generator = new CSharpGenerator(schema, new CSharpGeneratorSettings + { + ClassStyle = CSharpClassStyle.Record + }); + + //// Act + var output = generator.GenerateFile("Address"); + + //// Assert + Assert.Contains (@"public string Street { get; }", output); + Assert.DoesNotContain(@"public string Street { get; set; }", output); + + Assert.Contains("public Address(string Street, string City)", output); + Assert.Contains("public Address(string Street, string City)", output); + } + + public abstract class AbstractAddress + { + [JsonProperty("city")] + [DefaultValue("Innsmouth")] + public string City { get; set; } + + [JsonProperty("street")] + public string Street { get; set; } + } + + [Fact] + public async Task When_class_is_abstract_constructor_is_protected_for_record() + { + //// Arrange + var schema = await JsonSchema4.FromTypeAsync(); + var data = schema.ToJson(); + var generator = new CSharpGenerator(schema, new CSharpGeneratorSettings + { + ClassStyle = CSharpClassStyle.Record, + }); + + //// Act + var output = generator.GenerateFile("AbstractAddress"); + + //// Assert + Assert.Contains (@"public string Street { get; }", output); + Assert.DoesNotContain(@"public string Street { get; set; }", output); + + Assert.Contains("protected AbstractAddress(string street, string city = \"Innsmouth\")", output); + } } } diff --git a/src/NJsonSchema.CodeGeneration.CSharp/CSharpClassStyle.cs b/src/NJsonSchema.CodeGeneration.CSharp/CSharpClassStyle.cs index 301c43077..126362860 100644 --- a/src/NJsonSchema.CodeGeneration.CSharp/CSharpClassStyle.cs +++ b/src/NJsonSchema.CodeGeneration.CSharp/CSharpClassStyle.cs @@ -20,6 +20,9 @@ public enum CSharpClassStyle Inpc, /// Generates classes implementing the Prism base class. - Prism + Prism, + + /// Generates Records - read only POCOs (Plain Old C# Objects). + Record } } \ No newline at end of file diff --git a/src/NJsonSchema.CodeGeneration.CSharp/Models/ClassTemplateModel.cs b/src/NJsonSchema.CodeGeneration.CSharp/Models/ClassTemplateModel.cs index de582247b..190761132 100644 --- a/src/NJsonSchema.CodeGeneration.CSharp/Models/ClassTemplateModel.cs +++ b/src/NJsonSchema.CodeGeneration.CSharp/Models/ClassTemplateModel.cs @@ -70,6 +70,9 @@ public class ClassTemplateModel : ClassTemplateModelBase /// Gets a value indicating whether the class style is Prism. public bool RenderPrism => _settings.ClassStyle == CSharpClassStyle.Prism; + /// Gets a value indicating whether the class style is Record. + public bool RenderRecord => _settings.ClassStyle == CSharpClassStyle.Record; + /// Gets a value indicating whether to render ToJson() and FromJson() methods. public bool GenerateJsonMethods => _settings.GenerateJsonMethods; diff --git a/src/NJsonSchema.CodeGeneration.CSharp/NJsonSchema.CodeGeneration.CSharp.csproj b/src/NJsonSchema.CodeGeneration.CSharp/NJsonSchema.CodeGeneration.CSharp.csproj index 1d8262ddc..b6f51f456 100644 --- a/src/NJsonSchema.CodeGeneration.CSharp/NJsonSchema.CodeGeneration.CSharp.csproj +++ b/src/NJsonSchema.CodeGeneration.CSharp/NJsonSchema.CodeGeneration.CSharp.csproj @@ -23,6 +23,7 @@ + @@ -31,6 +32,7 @@ + diff --git a/src/NJsonSchema.CodeGeneration.CSharp/Templates/Class.Constructor.Record.liquid b/src/NJsonSchema.CodeGeneration.CSharp/Templates/Class.Constructor.Record.liquid new file mode 100644 index 000000000..f205cd02e --- /dev/null +++ b/src/NJsonSchema.CodeGeneration.CSharp/Templates/Class.Constructor.Record.liquid @@ -0,0 +1,9 @@ +{% assign skipComma = true -%} +{% assign sortedProperties = (Properties | sort: "HasDefaultValue") -%} +[Newtonsoft.Json.JsonConstructor] +{% if IsAbstract %}protected{% else %}public{% endif %} {{ClassName}}({% for property in sortedProperties -%}{% if skipComma -%}{% assign skipComma = false %}{% else %}, {% endif -%} {{ property.Type }} {{ property.Name }}{% if property.HasDefaultValue == true %} = {{ property.DefaultValue }}{% endif %}{% endfor -%}) +{ +{% for property in Properties -%} + this.{{property.PropertyName}} = @{{property.Name}}; +{% endfor -%} +} diff --git a/src/NJsonSchema.CodeGeneration.CSharp/Templates/Class.liquid b/src/NJsonSchema.CodeGeneration.CSharp/Templates/Class.liquid index 2c16807fe..6008eb929 100644 --- a/src/NJsonSchema.CodeGeneration.CSharp/Templates/Class.liquid +++ b/src/NJsonSchema.CodeGeneration.CSharp/Templates/Class.liquid @@ -18,6 +18,10 @@ {% endif -%} {% template Class.Constructor %} +{% if RenderRecord == true -%} + {% template Class.Constructor.Record %} + +{% endif -%} {% for property in Properties -%} {% if property.HasDescription -%} /// {{ property.Description | csharpdocs }} @@ -42,7 +46,7 @@ [Newtonsoft.Json.JsonConverter(typeof(DateFormatConverter))] {% endif -%} {% template Class.Property.Annotations %} - public {{ property.Type }} {{ property.PropertyName }}{% if RenderInpc == false and RenderPrism == false %} { get; {% if property.HasSetter %}set; {% endif %}}{% if property.HasDefaultValue %} = {{ property.DefaultValue }};{% endif %} + public {{ property.Type }} {{ property.PropertyName }}{% if RenderInpc == false and RenderPrism == false %} { get; {% if property.HasSetter and RenderRecord == false %}set; {% endif %}}{% if property.HasDefaultValue %} = {{ property.DefaultValue }};{% endif %} {% else %} { get { return {{ property.FieldName }}; } diff --git a/src/NJsonSchema.CodeGeneration/NJsonSchema.CodeGeneration.csproj b/src/NJsonSchema.CodeGeneration/NJsonSchema.CodeGeneration.csproj index a31120916..239dee27a 100644 --- a/src/NJsonSchema.CodeGeneration/NJsonSchema.CodeGeneration.csproj +++ b/src/NJsonSchema.CodeGeneration/NJsonSchema.CodeGeneration.csproj @@ -22,7 +22,7 @@ - +