diff --git a/src/NJsonSchema.CodeGeneration.CSharp/CSharpGenerator.cs b/src/NJsonSchema.CodeGeneration.CSharp/CSharpGenerator.cs
index 32b6d9fc3..d52e33aa2 100644
--- a/src/NJsonSchema.CodeGeneration.CSharp/CSharpGenerator.cs
+++ b/src/NJsonSchema.CodeGeneration.CSharp/CSharpGenerator.cs
@@ -59,7 +59,7 @@ public override string GenerateFile(string rootTypeNameHint)
var model = new FileTemplateModel
{
Namespace = Settings.Namespace ?? string.Empty,
- Classes = ConversionUtilities.TrimWhiteSpaces(_resolver.GenerateTypes().Concatenate())
+ TypesCode = ConversionUtilities.TrimWhiteSpaces(_resolver.GenerateTypes().Concatenate())
};
var template = Settings.TemplateFactory.CreateTemplate("CSharp", "File", model);
diff --git a/src/NJsonSchema.CodeGeneration.CSharp/CSharpTypeResolver.cs b/src/NJsonSchema.CodeGeneration.CSharp/CSharpTypeResolver.cs
index e4cadba2a..e7dd917a2 100644
--- a/src/NJsonSchema.CodeGeneration.CSharp/CSharpTypeResolver.cs
+++ b/src/NJsonSchema.CodeGeneration.CSharp/CSharpTypeResolver.cs
@@ -9,7 +9,6 @@
using System.Collections.Generic;
using System.Linq;
using NJsonSchema.CodeGeneration.CSharp.Models;
-using NJsonSchema.CodeGeneration.CSharp.Templates;
namespace NJsonSchema.CodeGeneration.CSharp
{
@@ -93,7 +92,8 @@ public override CodeArtifactCollection GenerateTypes()
Language = CodeArtifactLanguage.CSharp,
TypeName = "JsonInheritanceConverter",
- Code = new JsonInheritanceConverterTemplate(new JsonInheritanceConverterTemplateModel(Settings)).Render()
+ Code = Settings.TemplateFactory.CreateTemplate(
+ "CSharp", "JsonInheritanceConverter", new JsonInheritanceConverterTemplateModel(Settings)).Render()
});
}
@@ -105,7 +105,8 @@ public override CodeArtifactCollection GenerateTypes()
Language = CodeArtifactLanguage.CSharp,
TypeName = "DateFormatConverter",
- Code = new DateFormatConverterTemplate(new DateFormatConverterTemplateModel(Settings)).Render()
+ Code = Settings.TemplateFactory.CreateTemplate(
+ "CSharp", "DateFormatConverter", new DateFormatConverterTemplateModel(Settings)).Render()
});
}
diff --git a/src/NJsonSchema.CodeGeneration.CSharp/Models/ClassTemplateModel.cs b/src/NJsonSchema.CodeGeneration.CSharp/Models/ClassTemplateModel.cs
index 301e0196b..13ddfeb82 100644
--- a/src/NJsonSchema.CodeGeneration.CSharp/Models/ClassTemplateModel.cs
+++ b/src/NJsonSchema.CodeGeneration.CSharp/Models/ClassTemplateModel.cs
@@ -40,9 +40,6 @@ public ClassTemplateModel(string typeName, CSharpGeneratorSettings settings,
.ToList();
}
- /// Gets the NJsonSchema toolchain version.
- public string ToolchainVersion => JsonSchema4.ToolchainVersion;
-
/// Gets or sets the class name.
public override string ClassName { get; }
@@ -95,9 +92,15 @@ public string InheritanceCode
get
{
if (HasInheritance)
- return ": " + BaseClassName + (_settings.ClassStyle == CSharpClassStyle.Inpc ? ", System.ComponentModel.INotifyPropertyChanged" : "");
+ {
+ return ": " + BaseClassName + (_settings.ClassStyle == CSharpClassStyle.Inpc ?
+ ", System.ComponentModel.INotifyPropertyChanged" : "");
+ }
else
- return _settings.ClassStyle == CSharpClassStyle.Inpc ? ": System.ComponentModel.INotifyPropertyChanged" : "";
+ {
+ return _settings.ClassStyle == CSharpClassStyle.Inpc ?
+ ": System.ComponentModel.INotifyPropertyChanged" : "";
+ }
}
}
}
diff --git a/src/NJsonSchema.CodeGeneration.CSharp/Models/EnumTemplateModel.cs b/src/NJsonSchema.CodeGeneration.CSharp/Models/EnumTemplateModel.cs
index 385bb4e28..77801df39 100644
--- a/src/NJsonSchema.CodeGeneration.CSharp/Models/EnumTemplateModel.cs
+++ b/src/NJsonSchema.CodeGeneration.CSharp/Models/EnumTemplateModel.cs
@@ -15,7 +15,7 @@ namespace NJsonSchema.CodeGeneration.CSharp.Models
// TODO: Add base class for CSharp.EnumTemplateModel and TypeScript.EnumTemplateModel
/// The CSharp enum template model.
- public class EnumTemplateModel
+ public class EnumTemplateModel : TemplateModelBase
{
private readonly JsonSchema4 _schema;
private readonly CSharpGeneratorSettings _settings;
@@ -52,7 +52,7 @@ public IEnumerable Enums
get
{
var entries = new List();
- for (int i = 0; i < _schema.Enumeration.Count; i++)
+ for (var i = 0; i < _schema.Enumeration.Count; i++)
{
var value = _schema.Enumeration.ElementAt(i);
if (value != null)
@@ -69,6 +69,7 @@ public IEnumerable Enums
});
}
}
+
return entries;
}
}
diff --git a/src/NJsonSchema.CodeGeneration.CSharp/Models/FileTemplateModel.cs b/src/NJsonSchema.CodeGeneration.CSharp/Models/FileTemplateModel.cs
index c0f60cb59..070dff80f 100644
--- a/src/NJsonSchema.CodeGeneration.CSharp/Models/FileTemplateModel.cs
+++ b/src/NJsonSchema.CodeGeneration.CSharp/Models/FileTemplateModel.cs
@@ -14,7 +14,7 @@ public class FileTemplateModel
/// Gets or sets the namespace.
public string Namespace { get; set; }
- /// Gets or sets the classes code.
- public string Classes { get; set; }
+ /// Gets or sets the types code.
+ public string TypesCode { get; set; }
}
}
\ No newline at end of file
diff --git a/src/NJsonSchema.CodeGeneration.CSharp/NJsonSchema.CodeGeneration.CSharp.csproj b/src/NJsonSchema.CodeGeneration.CSharp/NJsonSchema.CodeGeneration.CSharp.csproj
index 38661b816..a05507430 100644
--- a/src/NJsonSchema.CodeGeneration.CSharp/NJsonSchema.CodeGeneration.CSharp.csproj
+++ b/src/NJsonSchema.CodeGeneration.CSharp/NJsonSchema.CodeGeneration.CSharp.csproj
@@ -21,7 +21,23 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/NJsonSchema.CodeGeneration.CSharp/Templates/DateFormatConverterTemplate.Extensions.cs b/src/NJsonSchema.CodeGeneration.CSharp/Templates/DateFormatConverterTemplate.Extensions.cs
index 3eec35bc4..57e995ee4 100644
--- a/src/NJsonSchema.CodeGeneration.CSharp/Templates/DateFormatConverterTemplate.Extensions.cs
+++ b/src/NJsonSchema.CodeGeneration.CSharp/Templates/DateFormatConverterTemplate.Extensions.cs
@@ -10,7 +10,7 @@
namespace NJsonSchema.CodeGeneration.CSharp.Templates
{
- internal partial class DateFormatConverterTemplate
+ internal partial class DateFormatConverterTemplate : ITemplate
{
public DateFormatConverterTemplate(DateFormatConverterTemplateModel model)
{
diff --git a/src/NJsonSchema.CodeGeneration.CSharp/Templates/FileTemplate.cs b/src/NJsonSchema.CodeGeneration.CSharp/Templates/FileTemplate.cs
index 4943cf15e..595e6d26e 100644
--- a/src/NJsonSchema.CodeGeneration.CSharp/Templates/FileTemplate.cs
+++ b/src/NJsonSchema.CodeGeneration.CSharp/Templates/FileTemplate.cs
@@ -44,7 +44,7 @@ public virtual string TransformText()
this.Write("\r\n{\r\n #pragma warning disable // Disable all warnings\r\n\r\n ");
#line 12 "C:\Data\Projects\NJsonSchema\src\NJsonSchema.CodeGeneration.CSharp\Templates\FileTemplate.tt"
- this.Write(this.ToStringHelper.ToStringWithCulture(ConversionUtilities.Tab(Model.Classes, 1)));
+ this.Write(this.ToStringHelper.ToStringWithCulture(ConversionUtilities.Tab(Model.TypesCode, 1)));
#line default
#line hidden
diff --git a/src/NJsonSchema.CodeGeneration.CSharp/Templates/FileTemplate.tt b/src/NJsonSchema.CodeGeneration.CSharp/Templates/FileTemplate.tt
index 4671ccf16..4b02a02ad 100644
--- a/src/NJsonSchema.CodeGeneration.CSharp/Templates/FileTemplate.tt
+++ b/src/NJsonSchema.CodeGeneration.CSharp/Templates/FileTemplate.tt
@@ -9,5 +9,5 @@ namespace <#=Model.Namespace#>
{
#pragma warning disable // Disable all warnings
- <#=ConversionUtilities.Tab(Model.Classes, 1)#>
+ <#=ConversionUtilities.Tab(Model.TypesCode, 1)#>
}
\ No newline at end of file
diff --git a/src/NJsonSchema.CodeGeneration.CSharp/Templates/JsonInheritanceConverterTemplate.Extensions.cs b/src/NJsonSchema.CodeGeneration.CSharp/Templates/JsonInheritanceConverterTemplate.Extensions.cs
index 2d5cdec59..7123d3fea 100644
--- a/src/NJsonSchema.CodeGeneration.CSharp/Templates/JsonInheritanceConverterTemplate.Extensions.cs
+++ b/src/NJsonSchema.CodeGeneration.CSharp/Templates/JsonInheritanceConverterTemplate.Extensions.cs
@@ -10,7 +10,7 @@
namespace NJsonSchema.CodeGeneration.CSharp.Templates
{
- internal partial class JsonInheritanceConverterTemplate
+ internal partial class JsonInheritanceConverterTemplate : ITemplate
{
public JsonInheritanceConverterTemplate(JsonInheritanceConverterTemplateModel model)
{
diff --git a/src/NJsonSchema.CodeGeneration.CSharp/Templates/Liquid/Class.FromJson.liquid b/src/NJsonSchema.CodeGeneration.CSharp/Templates/Liquid/Class.FromJson.liquid
new file mode 100644
index 000000000..020640500
--- /dev/null
+++ b/src/NJsonSchema.CodeGeneration.CSharp/Templates/Liquid/Class.FromJson.liquid
@@ -0,0 +1,4 @@
+public static {{ ClassName }} FromJson(string data)
+{
+ return Newtonsoft.Json.JsonConvert.DeserializeObject<{{ ClassName }}>(data{{ JsonSerializerParameterCode }});
+}
\ No newline at end of file
diff --git a/src/NJsonSchema.CodeGeneration.CSharp/Templates/Liquid/Class.Inpc.liquid b/src/NJsonSchema.CodeGeneration.CSharp/Templates/Liquid/Class.Inpc.liquid
new file mode 100644
index 000000000..67b1d44a3
--- /dev/null
+++ b/src/NJsonSchema.CodeGeneration.CSharp/Templates/Liquid/Class.Inpc.liquid
@@ -0,0 +1,8 @@
+public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
+
+protected virtual void RaisePropertyChanged([System.Runtime.CompilerServices.CallerMemberName] string propertyName = null)
+{
+ var handler = PropertyChanged;
+ if (handler != null)
+ handler(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
+}
\ No newline at end of file
diff --git a/src/NJsonSchema.CodeGeneration.CSharp/Templates/Liquid/Class.ToJson.liquid b/src/NJsonSchema.CodeGeneration.CSharp/Templates/Liquid/Class.ToJson.liquid
new file mode 100644
index 000000000..7505b8588
--- /dev/null
+++ b/src/NJsonSchema.CodeGeneration.CSharp/Templates/Liquid/Class.ToJson.liquid
@@ -0,0 +1,4 @@
+public string ToJson()
+{
+ return Newtonsoft.Json.JsonConvert.SerializeObject(this{{ JsonSerializerParameterCode }});
+}
\ No newline at end of file
diff --git a/src/NJsonSchema.CodeGeneration.CSharp/Templates/Class.liquid b/src/NJsonSchema.CodeGeneration.CSharp/Templates/Liquid/Class.liquid
similarity index 81%
rename from src/NJsonSchema.CodeGeneration.CSharp/Templates/Class.liquid
rename to src/NJsonSchema.CodeGeneration.CSharp/Templates/Liquid/Class.liquid
index c8b4e64da..06236a112 100644
--- a/src/NJsonSchema.CodeGeneration.CSharp/Templates/Class.liquid
+++ b/src/NJsonSchema.CodeGeneration.CSharp/Templates/Liquid/Class.liquid
@@ -67,26 +67,11 @@
}
{%- endif -%}
-{%- if RenderInpc -%}
- public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
-
-{%- endif -%}
- public string ToJson()
- {
- return Newtonsoft.Json.JsonConvert.SerializeObject(this{{ JsonSerializerParameterCode }});
- }
+ {% template ToJson %}
- public static {{ ClassName }} FromJson(string data)
- {
- return Newtonsoft.Json.JsonConvert.DeserializeObject<{{ ClassName }}>(data{{ JsonSerializerParameterCode }});
- }
+ {% template FromJson %}
{%- if RenderInpc -%}
- protected virtual void RaisePropertyChanged([System.Runtime.CompilerServices.CallerMemberName] string propertyName = null)
- {
- var handler = PropertyChanged;
- if (handler != null)
- handler(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
- }
+ {% template Inpc %}
{%- endif -%}
}
\ No newline at end of file
diff --git a/src/NJsonSchema.CodeGeneration.CSharp/Templates/Liquid/DateFormatConverter.liquid b/src/NJsonSchema.CodeGeneration.CSharp/Templates/Liquid/DateFormatConverter.liquid
new file mode 100644
index 000000000..612652bfc
--- /dev/null
+++ b/src/NJsonSchema.CodeGeneration.CSharp/Templates/Liquid/DateFormatConverter.liquid
@@ -0,0 +1,10 @@
+{%- if GenerateDateFormatConverterClass -%}
+[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "{{ ToolchainVersion }}")]
+internal class DateFormatConverter : Newtonsoft.Json.Converters.IsoDateTimeConverter
+{
+ public DateFormatConverter()
+ {
+ DateTimeFormat = "yyyy-MM-dd";
+ }
+}
+{%- endif -%}
\ No newline at end of file
diff --git a/src/NJsonSchema.CodeGeneration.CSharp/Templates/Liquid/Enum.liquid b/src/NJsonSchema.CodeGeneration.CSharp/Templates/Liquid/Enum.liquid
new file mode 100644
index 000000000..17c3f6866
--- /dev/null
+++ b/src/NJsonSchema.CodeGeneration.CSharp/Templates/Liquid/Enum.liquid
@@ -0,0 +1,14 @@
+{%- if HasDescription -%}
+/// {{ Description | CSharpDocs }}
+{%- endif -%}
+[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "{{ ToolchainVersion }}")]
+{{ TypeAccessModifier }} enum {{ Name }}
+{
+{%- for enum in Enums -%}
+{%- if IsStringEnum -%}
+ [System.Runtime.Serialization.EnumMember(Value = "{{ enum.Value }}")]
+{%- endif -%}
+ {{ enum.Name }} = {{ enum.InternalValue }},
+
+{%- endfor -%}
+}
\ No newline at end of file
diff --git a/src/NJsonSchema.CodeGeneration.CSharp/Templates/Liquid/File.liquid b/src/NJsonSchema.CodeGeneration.CSharp/Templates/Liquid/File.liquid
new file mode 100644
index 000000000..770bf847a
--- /dev/null
+++ b/src/NJsonSchema.CodeGeneration.CSharp/Templates/Liquid/File.liquid
@@ -0,0 +1,12 @@
+//----------------------
+//
+// Generated using the NJsonSchema v{{ ToolchainVersion }} (http://NJsonSchema.org)
+//
+//----------------------
+
+namespace {{ Namespace }}
+{
+ #pragma warning disable // Disable all warnings
+
+ {{ TypesCode | tab: 1 }}
+}
\ No newline at end of file
diff --git a/src/NJsonSchema.CodeGeneration.CSharp/Templates/Liquid/JsonInheritanceConverter.liquid b/src/NJsonSchema.CodeGeneration.CSharp/Templates/Liquid/JsonInheritanceConverter.liquid
new file mode 100644
index 000000000..80223b4f9
--- /dev/null
+++ b/src/NJsonSchema.CodeGeneration.CSharp/Templates/Liquid/JsonInheritanceConverter.liquid
@@ -0,0 +1,120 @@
+{%- if GenerateJsonInheritanceAttributeClass -%}
+[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "{{ ToolchainVersion }}")]
+[System.AttributeUsage(System.AttributeTargets.Class, AllowMultiple = true)]
+internal class JsonInheritanceAttribute : System.Attribute
+{
+ public JsonInheritanceAttribute(string key, System.Type type)
+ {
+ Key = key;
+ Type = type;
+ }
+
+ public string Key { get; }
+
+ public System.Type Type { get; }
+}
+
+{%- endif -%}
+{%- if GenerateJsonInheritanceConverterClass -%}
+[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "{{ ToolchainVersion }}")]
+internal class JsonInheritanceConverter : Newtonsoft.Json.JsonConverter
+{
+ internal static readonly string DefaultDiscriminatorName = "discriminator";
+
+ private readonly string _discriminator;
+
+ [System.ThreadStatic]
+ private static bool _isReading;
+
+ [System.ThreadStatic]
+ private static bool _isWriting;
+
+ public JsonInheritanceConverter()
+ {
+ _discriminator = DefaultDiscriminatorName;
+ }
+
+ public JsonInheritanceConverter(string discriminator)
+ {
+ _discriminator = discriminator;
+ }
+
+ public override void WriteJson(Newtonsoft.Json.JsonWriter writer, object value, Newtonsoft.Json.JsonSerializer serializer)
+ {
+ try
+ {
+ _isWriting = true;
+
+ var jObject = Newtonsoft.Json.Linq.JObject.FromObject(value, serializer);
+ jObject.AddFirst(new Newtonsoft.Json.Linq.JProperty(_discriminator, value.GetType().Name));
+ writer.WriteToken(jObject.CreateReader());
+ }
+ finally
+ {
+ _isWriting = false;
+ }
+ }
+
+ public override bool CanWrite
+ {
+ get
+ {
+ if (_isWriting)
+ {
+ _isWriting = false;
+ return false;
+ }
+ return true;
+ }
+ }
+
+ public override bool CanRead
+ {
+ get
+ {
+ if (_isReading)
+ {
+ _isReading = false;
+ return false;
+ }
+ return true;
+ }
+ }
+
+ public override bool CanConvert(System.Type objectType)
+ {
+ return true;
+ }
+
+ public override object ReadJson(Newtonsoft.Json.JsonReader reader, System.Type objectType, object existingValue, Newtonsoft.Json.JsonSerializer serializer)
+ {
+ var jObject = serializer.Deserialize(reader);
+ if (jObject == null)
+ return null;
+
+ var discriminator = Newtonsoft.Json.Linq.Extensions.Value(jObject.GetValue(_discriminator));
+ var subtype = GetObjectSubtype(objectType, discriminator);
+
+ try
+ {
+ _isReading = true;
+ return serializer.Deserialize(jObject.CreateReader(), subtype);
+ }
+ finally
+ {
+ _isReading = false;
+ }
+ }
+
+ private System.Type GetObjectSubtype(System.Type objectType, string discriminator)
+ {
+ foreach (var type in System.Reflection.CustomAttributeExtensions.GetCustomAttributes(System.Reflection.IntrospectionExtensions.GetTypeInfo(objectType), false))
+ {
+ if (type.Key == discriminator)
+ return type.Type;
+ }
+
+ return objectType;
+ }
+}
+{%- endif -%}
\ No newline at end of file
diff --git a/src/NJsonSchema.CodeGeneration/CodeGeneratorSettingsBase.cs b/src/NJsonSchema.CodeGeneration/CodeGeneratorSettingsBase.cs
index 8c4329fed..d7eaa34d0 100644
--- a/src/NJsonSchema.CodeGeneration/CodeGeneratorSettingsBase.cs
+++ b/src/NJsonSchema.CodeGeneration/CodeGeneratorSettingsBase.cs
@@ -18,6 +18,10 @@ public CodeGeneratorSettingsBase()
{
GenerateDefaultValues = true;
ExcludedTypeNames = new string[] { };
+
+#if DEBUG
+ UseLiquidTemplates = true;
+#endif
}
/// Gets or sets the schema type (default: JsonSchema).
@@ -46,6 +50,9 @@ public CodeGeneratorSettingsBase()
public ITemplateFactory TemplateFactory { get; set; }
/// Gets or sets a value indicating whether to use DotLiquid templates (experimental).
- public bool UseLiquidTemplates { get; set; } = true;
+ public bool UseLiquidTemplates { get; set; }
+
+ /// Gets or sets the template directory path.
+ public string TemplateDirectory { get; set; }
}
}
\ No newline at end of file
diff --git a/src/NJsonSchema.CodeGeneration/DefaultTemplateFactory.cs b/src/NJsonSchema.CodeGeneration/DefaultTemplateFactory.cs
index 056c6f1ba..10e8ee5e0 100644
--- a/src/NJsonSchema.CodeGeneration/DefaultTemplateFactory.cs
+++ b/src/NJsonSchema.CodeGeneration/DefaultTemplateFactory.cs
@@ -26,46 +26,70 @@ public DefaultTemplateFactory(CodeGeneratorSettingsBase settings)
/// Creates a template for the given language, template name and template model.
/// Supports NJsonSchema and NSwag embedded templates.
- /// The package name (i.e. language).
+ /// The language.
/// The template name.
/// The template model.
/// The template.
/// Could not load template..
- public virtual ITemplate CreateTemplate(string package, string template, object model)
+ public virtual ITemplate CreateTemplate(string language, string template, object model)
{
- if (_settings.UseLiquidTemplates)
+ var liquidTemplate = TryGetLiquidTemplate(language, template);
+ if (liquidTemplate != null)
+ return new LiquidTemplate(language, template, liquidTemplate, model, _settings);
+ else
+ return CreateT4Template(language, template, model);
+ }
+
+ /// Tries to load a Liquid template from an embedded resource.
+ /// The language.
+ /// The template name.
+ /// The template.
+ protected virtual string TryLoadEmbeddedLiquidTemplate(string language, string template)
+ {
+ var assembly = Assembly.Load(new AssemblyName("NJsonSchema.CodeGeneration." + language));
+ var resourceName = "NJsonSchema.CodeGeneration." + language + ".Templates.Liquid." + template + ".liquid";
+
+ var resource = assembly.GetManifestResourceStream(resourceName);
+ if (resource != null)
{
- var assembly = Assembly.Load(new AssemblyName("NJsonSchema.CodeGeneration." + package));
- var resourceName = "NJsonSchema.CodeGeneration." + package + ".Templates." + template + ".liquid";
+ using (var reader = new StreamReader(resource))
+ return reader.ReadToEnd();
+ }
- var resource = assembly.GetManifestResourceStream(resourceName);
- if (resource != null)
- {
- using (var reader = new StreamReader(resource))
- return new LiquidTemplate(reader.ReadToEnd(), model);
- }
- else
+ return null;
+ }
+
+ private string TryGetLiquidTemplate(string language, string template)
+ {
+ if (_settings.UseLiquidTemplates)
+ {
+ if (!template.EndsWith("!") &&
+ !string.IsNullOrEmpty(_settings.TemplateDirectory) &&
+ Directory.Exists(_settings.TemplateDirectory))
{
- return CreateT4Template(package, template, model);
+ var templateFilePath = Path.Combine(_settings.TemplateDirectory, language, template + ".liquid");
+ if (File.Exists(templateFilePath))
+ return File.ReadAllText(templateFilePath);
}
+
+ return TryLoadEmbeddedLiquidTemplate(language, template.TrimEnd('!'));
}
- else
- {
- return CreateT4Template(package, template, model);
- }
+
+ return null;
}
- private ITemplate CreateT4Template(string package, string template, object model)
+ /// Could not load template..
+ private ITemplate CreateT4Template(string language, string template, object model)
{
- var typeName = "NJsonSchema.CodeGeneration." + package + ".Templates." + template + "Template";
+ var typeName = "NJsonSchema.CodeGeneration." + language + ".Templates." + template + "Template";
var type = Type.GetType(typeName);
if (type == null)
- type = Assembly.Load(new AssemblyName("NJsonSchema.CodeGeneration." + package))?.GetType(typeName);
+ type = Assembly.Load(new AssemblyName("NJsonSchema.CodeGeneration." + language))?.GetType(typeName);
if (type != null)
- return (ITemplate) Activator.CreateInstance(type, model);
+ return (ITemplate)Activator.CreateInstance(type, model);
- throw new InvalidOperationException("Could not load template '" + template + "'.");
+ throw new InvalidOperationException("Could not load template '" + template + "' for language '" + language + "'.");
}
}
}
\ No newline at end of file
diff --git a/src/NJsonSchema.CodeGeneration/LiquidTemplate.cs b/src/NJsonSchema.CodeGeneration/LiquidTemplate.cs
index a42f1c778..a534d6b84 100644
--- a/src/NJsonSchema.CodeGeneration/LiquidTemplate.cs
+++ b/src/NJsonSchema.CodeGeneration/LiquidTemplate.cs
@@ -6,31 +6,50 @@
// Rico Suter, mail@rsuter.com
//-----------------------------------------------------------------------
+using System.Collections.Generic;
+using System.IO;
+using System.Text.RegularExpressions;
using DotLiquid;
namespace NJsonSchema.CodeGeneration
{
internal class LiquidTemplate : ITemplate
{
+ private readonly string _language;
private readonly string _template;
+ private readonly string _data;
private readonly object _model;
+ private readonly CodeGeneratorSettingsBase _settings;
- public LiquidTemplate(string template, object model)
+ public LiquidTemplate(string language, string template, string data, object model, CodeGeneratorSettingsBase settings)
{
+ _language = language;
_template = template;
+ _data = data;
_model = model;
+ _settings = settings;
}
public string Render()
{
- var tpl = Template.Parse(_template);
- var hash = LiquidHash.FromObject(_model);
- // TODO: Check models here
- return tpl.Render(new RenderParameters
+ Template.RegisterTag("template");
+
+ var data = Regex.Replace(_data, "(\n(( )*?)\\{% template .*?) %}", m =>
+ m.Groups[1].Value + " " + m.Groups[2].Value.Length / 4 + " %}",
+ RegexOptions.Singleline);
+
+ var template = Template.Parse(data);
+
+ var hash = _model is Hash ? (Hash)_model : LiquidHash.FromObject(_model);
+ hash[TemplateTag.LanguageKey] = _language;
+ hash[TemplateTag.TemplateKey] = _template;
+ hash[TemplateTag.SettingsKey] = _settings;
+
+ return template.Render(new RenderParameters
{
LocalVariables = hash,
Filters = new[] { typeof(LiquidFilters) }
- }).Trim('\r', '\n', ' ');
+ });
}
}
@@ -38,8 +57,45 @@ internal static class LiquidFilters
{
public static string CSharpDocs(string input)
{
- // TODO: Check if this is really called!
return ConversionUtilities.ConvertCSharpDocBreaks(input, 0);
}
+
+ public static string Tab(Context context, string input, int tabCount)
+ {
+ return ConversionUtilities.Tab(input, tabCount);
+ }
+ }
+
+ internal class TemplateTag : Tag
+ {
+ public static string LanguageKey = "__language";
+ public static string TemplateKey = "__template";
+ public static string SettingsKey = "__settings";
+
+ private string _template;
+ private int _tab;
+
+ public override void Initialize(string tagName, string markup, List tokens)
+ {
+ var parts = markup.Trim().Split(' ');
+ _template = parts[0];
+ _tab = parts.Length == 2 ? int.Parse(parts[1]) : 0;
+ base.Initialize(tagName, markup, tokens);
+ }
+
+ public override void Render(Context context, TextWriter result)
+ {
+ var hash = new Hash();
+ foreach (var environment in context.Environments)
+ hash.Merge(environment);
+
+ var settings = (CodeGeneratorSettingsBase)hash[SettingsKey];
+ var template = settings.TemplateFactory.CreateTemplate(
+ (string)hash[LanguageKey],
+ !string.IsNullOrEmpty(_template) ? (string)hash[TemplateKey] + "." + _template : (string)hash[TemplateKey] + "!",
+ hash);
+
+ result.Write(ConversionUtilities.Tab(template.Render(), _tab));
+ }
}
}
\ No newline at end of file
diff --git a/src/NJsonSchema.CodeGeneration/Models/ClassTemplateModelBase.cs b/src/NJsonSchema.CodeGeneration/Models/ClassTemplateModelBase.cs
index a18d04750..6d3af3004 100644
--- a/src/NJsonSchema.CodeGeneration/Models/ClassTemplateModelBase.cs
+++ b/src/NJsonSchema.CodeGeneration/Models/ClassTemplateModelBase.cs
@@ -12,7 +12,7 @@
namespace NJsonSchema.CodeGeneration.Models
{
/// The class template base class.
- public abstract class ClassTemplateModelBase
+ public abstract class ClassTemplateModelBase : TemplateModelBase
{
private readonly JsonSchema4 _schema;
private readonly object _rootObject;
diff --git a/src/NJsonSchema.CodeGeneration/Models/TemplateModelBase.cs b/src/NJsonSchema.CodeGeneration/Models/TemplateModelBase.cs
new file mode 100644
index 000000000..6fce3deeb
--- /dev/null
+++ b/src/NJsonSchema.CodeGeneration/Models/TemplateModelBase.cs
@@ -0,0 +1,17 @@
+//-----------------------------------------------------------------------
+//
+// Copyright (c) Rico Suter. All rights reserved.
+//
+// https://github.com/rsuter/NJsonSchema/blob/master/LICENSE.md
+// Rico Suter, mail@rsuter.com
+//-----------------------------------------------------------------------
+
+namespace NJsonSchema.CodeGeneration.Models
+{
+ /// The base template model.
+ public class TemplateModelBase
+ {
+ /// Gets the NJsonSchema toolchain version.
+ public string ToolchainVersion => JsonSchema4.ToolchainVersion;
+ }
+}