From 1b2f99223d69b6af64b2eb82fca6aeafd7f7a703 Mon Sep 17 00:00:00 2001 From: mbsoftlab <50733221+mbsoftlab@users.noreply.github.com> Date: Fri, 25 Dec 2020 15:13:55 +0100 Subject: [PATCH 01/28] TE-1 Reading TemplateDataModel from JSON (#5) * TE-1 Added Extension Methods for reading data from JSON * TE-1 Update Readme for v1.0.8-preview * TE-1 Renamed Method CreateStringFromTemplateWithJson * TE-1 Renamed Tests * TE-1 Update AssemblyVersion and FileVersion --- .../DummyJsonData.json | 15 +++ ...MbSoftLab.TemplateEngine.Core.Tests.csproj | 10 +- .../TemplateEngineUnitTest.cs | 38 +++---- .../UnitTestBase.cs | 4 + .../Documentation.xml | 99 +++++++++++++++++++ .../MbSoftLab.TemplateEngine.Core.csproj | 8 +- .../TemplateEngine.cs | 13 +-- .../TemplateEngineExtensions.cs | 24 +++++ README.md | 2 + 9 files changed, 175 insertions(+), 38 deletions(-) create mode 100644 MbSoftLab.TemplateEngine.Core.Tests/DummyJsonData.json create mode 100644 MbSoftLab.TemplateEngine.Core/Documentation.xml create mode 100644 MbSoftLab.TemplateEngine.Core/TemplateEngineExtensions.cs diff --git a/MbSoftLab.TemplateEngine.Core.Tests/DummyJsonData.json b/MbSoftLab.TemplateEngine.Core.Tests/DummyJsonData.json new file mode 100644 index 0000000..9bb5dad --- /dev/null +++ b/MbSoftLab.TemplateEngine.Core.Tests/DummyJsonData.json @@ -0,0 +1,15 @@ +{ + "DummyStringProp1": "DummyStringProp1Value", + "DummyIntProp1": 1, + "DummBoolProp1": true, + "DummyBoolQProp1": true, + "DummyDoubleProp1": 1.75, + "DummyDateTimeProp1": "2020-01-01T00:00:00", + "DummyInt64Prop": 1234567, + "DummyUInt16": 8, + "DummyInt16": -8, + "DummyDecimalProp": 55, + "DummyCharProp": "c", + "DummyByteProp": 255, + "DummySByteProp": -5 +} \ No newline at end of file diff --git a/MbSoftLab.TemplateEngine.Core.Tests/MbSoftLab.TemplateEngine.Core.Tests.csproj b/MbSoftLab.TemplateEngine.Core.Tests/MbSoftLab.TemplateEngine.Core.Tests.csproj index f95803f..7501a7f 100644 --- a/MbSoftLab.TemplateEngine.Core.Tests/MbSoftLab.TemplateEngine.Core.Tests.csproj +++ b/MbSoftLab.TemplateEngine.Core.Tests/MbSoftLab.TemplateEngine.Core.Tests.csproj @@ -8,12 +8,18 @@ - - + + + + + Always + + + \ No newline at end of file diff --git a/MbSoftLab.TemplateEngine.Core.Tests/TemplateEngineUnitTest.cs b/MbSoftLab.TemplateEngine.Core.Tests/TemplateEngineUnitTest.cs index 7c3bc32..5dd3ef1 100644 --- a/MbSoftLab.TemplateEngine.Core.Tests/TemplateEngineUnitTest.cs +++ b/MbSoftLab.TemplateEngine.Core.Tests/TemplateEngineUnitTest.cs @@ -12,9 +12,8 @@ public class TemplateEngineUnitTest : UnitTestBase { [Test] - public void can_create_a_valid_template() + public void can_create_a_valid_string_from_template() { - //Arrange var sut = new TemplateEngine(GetTemplateDataModelDummy(), "${DummyStringProp1}"); //SUT = [S]ystem [U]nder [T]est string ShouldReturnString = "DummyStringProp1Value"; @@ -22,6 +21,20 @@ public void can_create_a_valid_template() //Act Ausführen der zu testenden Funktion string ReturnString = sut.CreateStringFromTemplate(); + //Assert + Assert.AreEqual(ShouldReturnString, ReturnString); + } + [Test] + public void can_create_a_valid_string_from_template_with_json() + { + //Arrange + var sut = new TemplateEngine(); //SUT = [S]ystem [U]nder [T]est + sut.TemplateString = "${DummyStringProp1}"; + string ShouldReturnString = "DummyStringProp1Value"; + string jsonData = GetDummyJson(); + + //Act Ausführen der zu testenden Funktion + string ReturnString = sut.CreateStringFromTemplateWithJson(jsonData); //Assert Assert.AreEqual(ShouldReturnString, ReturnString); @@ -29,7 +42,6 @@ public void can_create_a_valid_template() [Test] public void can_handle_null_Values_in_Propertys() { - //Arrange var sut = new TemplateEngine(GetTemplateDataModelDummy(), "${DummyStringProp2}"); //SUT = [S]ystem [U]nder [T]est string ShouldReturnString = "NULL"; @@ -37,14 +49,12 @@ public void can_handle_null_Values_in_Propertys() //Act Ausführen der zu testenden Funktion string ReturnString = sut.CreateStringFromTemplate(); - //Assert Assert.AreEqual(ShouldReturnString, ReturnString); } [Test] public void can_set_a_custom_null_value_String() { - //Arrange var sut = new TemplateEngine(GetTemplateDataModelDummy(), "${DummyStringProp2}"); //SUT = [S]ystem [U]nder [T]est sut.NullStringValue = "Nothing"; @@ -53,7 +63,6 @@ public void can_set_a_custom_null_value_String() //Act string ReturnString = sut.CreateStringFromTemplate(); - //Assert Assert.AreEqual(ShouldReturnString, ReturnString); } @@ -69,7 +78,6 @@ public void can_set_a_template() //Act string ReturnString = sut.CreateStringFromTemplate(); - //Assert Assert.AreEqual(ShouldReturnString, ReturnString); } @@ -94,7 +102,6 @@ public void can_use_the_config() //Act string ReturnString = sut.CreateStringFromTemplate(); - //Assert Assert.AreEqual(ShouldReturnString, ReturnString); } @@ -119,7 +126,6 @@ public void can_use_the_generic_config() //Act string ReturnString = sut.CreateStringFromTemplate(); - //Assert Assert.AreEqual(ShouldReturnString, ReturnString); } @@ -134,7 +140,6 @@ public void can_set_a_template_and_model_on_creating() //Act string ReturnString = sut.CreateStringFromTemplate(GetTemplateDataModelDummy(), "${DummyStringProp2}"); - //Assert Assert.AreEqual(ShouldReturnString, ReturnString); } @@ -150,7 +155,6 @@ public void can_set_a_model_on_creating() //Act string ReturnString = sut.CreateStringFromTemplate(GetTemplateDataModelDummy()); - //Assert Assert.AreEqual(ShouldReturnString, ReturnString); } @@ -166,7 +170,6 @@ public void can_set_a_DataModel_with_Annonymos_Type() //Act string ReturnString = sut.CreateStringFromTemplate(); - //Assert Assert.AreEqual(ShouldReturnString, ReturnString); } @@ -183,7 +186,6 @@ public void can_set_a_different_DataModel_with_annonymos_type_after_create_an_in //Act string ReturnString = sut.CreateStringFromTemplate(); - //Assert Assert.AreEqual(ShouldReturnString, ReturnString); } @@ -202,7 +204,6 @@ public void can_change_the_default_delimiters() //Act string ReturnString = sut.CreateStringFromTemplate(); - //Assert Assert.AreEqual(ShouldReturnString, ReturnString); } @@ -212,14 +213,12 @@ public void throws_exeption_if_type_not_supported() //Arrange var sut = new TemplateEngine(GetAWrongTemplateDataModelDummy(), "${DummyObjectProp1}"); //SUT = [S]ystem [U]nder [T]est - //Assert Assert.Throws(delegate { //Act sut.CreateStringFromTemplate(); }); - } [Test] public void throws_excepton_if_file_load_fail() @@ -264,7 +263,6 @@ public void can_handle_return_values_from_a_method(string methodName, string ret //Act string ReturnString = sut.CreateStringFromTemplate(); - //Assert Assert.AreEqual(ShouldReturnString, ReturnString); } @@ -281,7 +279,6 @@ public void can_handle_return_values_from_IntReturningMethod() //Act string ReturnString = sut.CreateStringFromTemplate(); - //Assert Assert.AreEqual(ShouldReturnString, ReturnString); } @@ -299,7 +296,6 @@ public void can_handle_return_values_from_DoubleReturningMethod() //Act string ReturnString = sut.CreateStringFromTemplate(); - //Assert Assert.AreEqual(ShouldReturnString, ReturnString); } @@ -359,7 +355,6 @@ public void can_handle_date_values_from_propertys() //Act Ausführen der zu testenden Funktion string ReturnString = sut.CreateStringFromTemplate(); - //Assert Prüfen der Ergebnisse Assert.AreEqual(ShouldReturnString, ReturnString); } @@ -380,6 +375,5 @@ public void can_create_and_use_SpecificCulture() //Assert Assert.AreEqual(ShouldReturnString, ReturnString); } - } -} +} \ No newline at end of file diff --git a/MbSoftLab.TemplateEngine.Core.Tests/UnitTestBase.cs b/MbSoftLab.TemplateEngine.Core.Tests/UnitTestBase.cs index b94bc4f..495ac5e 100644 --- a/MbSoftLab.TemplateEngine.Core.Tests/UnitTestBase.cs +++ b/MbSoftLab.TemplateEngine.Core.Tests/UnitTestBase.cs @@ -53,6 +53,10 @@ public TemplateDataModelDummy GetTemplateDataModelDummy() return templateDataModelFake; } + public string GetDummyJson() + { + return System.IO.File.ReadAllText("DummyJsonData.json"); + } public TemplateDataModelDummyWithList GetTemplateDataModelDummyWithListAndMethod() { TemplateDataModelDummyWithList templateDataModelFake = new TemplateDataModelDummyWithList diff --git a/MbSoftLab.TemplateEngine.Core/Documentation.xml b/MbSoftLab.TemplateEngine.Core/Documentation.xml new file mode 100644 index 0000000..4d0663d --- /dev/null +++ b/MbSoftLab.TemplateEngine.Core/Documentation.xml @@ -0,0 +1,99 @@ + + + + MbSoftLab.TemplateEngine.Core + + + + + + + + + + + + + + + + A simple StringTemplateengine for .NET.

+ See for more details +
+
+ + + Beginning Char for a PlaceholderProperty. The Defaultvalue ist "${". + + + + + Ending Char for a PlaceholderProperty. Der Default ist "}". + + + + + Model with propertys to fill ${PlaceholderPropertys} in the template. The propertynames at DataModel has to be equal with ${Placeholder} + + + + + The Templatestring with ${PlaceholderPropertys} + + + + + Get or Set the string for NULL-Values. Default = NULL. + + + + + Replaces all Propertys of templateDataModel in stringTemplate. The Popertynames from templateDataModel a the name of ${Placeholder} have to be equal. + Example: public string MyProperty => ${MyProperty} + + File with Data from TemplateDataModel + + + + Replaces all Propertys of templateDataModel in stringTemplate. The Popertynames from templateDataModel a the name of ${Placeholder} have to be equal. + Example: public string MyProperty => ${MyProperty} + + File with Data from TemplateDataModel + + + + Replaces all Propertys of templateDataModel in stringTemplate. The Popertynames from templateDataModel a the name of ${Placeholder} have to be equal. + Example: public string MyProperty => ${MyProperty} + + File with Data from TemplateDataModel + + + + Replaces all Propertys of templateDataModel in stringTemplate. The Popertynames from templateDataModel a the name of ${Placeholder} have to be equal. + Example: public string MyProperty => ${MyProperty} + + File with Data from TemplateDataModel + + + + + + + + + + + + + + Load the TemplateDataModel from JSON and builds a String with this Data + + + + + Loads a Templatestring from File + + Path to File with Templatestring. + +
+
diff --git a/MbSoftLab.TemplateEngine.Core/MbSoftLab.TemplateEngine.Core.csproj b/MbSoftLab.TemplateEngine.Core/MbSoftLab.TemplateEngine.Core.csproj index 93c7b12..bff15ab 100644 --- a/MbSoftLab.TemplateEngine.Core/MbSoftLab.TemplateEngine.Core.csproj +++ b/MbSoftLab.TemplateEngine.Core/MbSoftLab.TemplateEngine.Core.csproj @@ -2,10 +2,10 @@ netcoreapp3.1 - 1.0.7.0 - 1.0.7.0 - 1.0.7 - 1.0.7 + 1.0.8.0 + 1.0.8.0 + 1.0.8 + 1.0.8-preview This StringTemplateEngine can replace values from Classpropertys and methods in stringtemplates Documentation.xml true diff --git a/MbSoftLab.TemplateEngine.Core/TemplateEngine.cs b/MbSoftLab.TemplateEngine.Core/TemplateEngine.cs index 8612bce..e223663 100644 --- a/MbSoftLab.TemplateEngine.Core/TemplateEngine.cs +++ b/MbSoftLab.TemplateEngine.Core/TemplateEngine.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Globalization; +using System.Text.Json; namespace MbSoftLab.TemplateEngine.Core { @@ -93,22 +94,14 @@ public TemplateEngine(T templateDataModel) { _templateDataModel = templateDataModel; } - + public TemplateEngine() { } #endregion - /// - /// Loads a Templatestring from File - /// - /// Path to File with Templatestring. - public void LoadTemplateFromFile(string path) - { - TemplateString = System.IO.File.ReadAllText(path); - } - + /// /// Replaces all Propertys of templateDataModel in stringTemplate. The Popertynames from templateDataModel a the name of ${Placeholder} have to be equal. /// Example: public string MyProperty => ${MyProperty} diff --git a/MbSoftLab.TemplateEngine.Core/TemplateEngineExtensions.cs b/MbSoftLab.TemplateEngine.Core/TemplateEngineExtensions.cs new file mode 100644 index 0000000..f23cd00 --- /dev/null +++ b/MbSoftLab.TemplateEngine.Core/TemplateEngineExtensions.cs @@ -0,0 +1,24 @@ +using System.Text.Json; + +namespace MbSoftLab.TemplateEngine.Core +{ + public static class TemplateEngineExtensions + { + /// + /// Load the TemplateDataModel from JSON and builds a String with this Data + /// + public static string CreateStringFromTemplateWithJson(this TemplateEngine templateEngine, string jsonData) + { + templateEngine.TemplateDataModel = JsonSerializer.Deserialize(jsonData); + return templateEngine.CreateStringFromTemplate(); + } + /// + /// Loads a Templatestring from File + /// + /// Path to File with Templatestring. + public static void LoadTemplateFromFile(this TemplateEngine templateEngine, string path) + { + templateEngine.TemplateString = System.IO.File.ReadAllText(path); + } + } +} \ No newline at end of file diff --git a/README.md b/README.md index 304a10c..3f72cfe 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,8 @@ PM> Install-Package MbSoftLab.TemplateEngine.Core |Methodname |Description | |------------------------------------------------------------------------|-----------------------------------------------------------------| |`string CreateStringFromTemplate([string template])` |*Creates a String from Datamodell and Template* | +|`string CreateStringFromJson(templateEngine, string jsonData)` |*Loads the Templatedata from JSON*. + | |`void LoadTemplateFromFile(string filename)` |*Loads a Stringtemplate from file*. | |`TemplateEngine()` |Constructor | |`TemplateEngine(object templateDataModel, string stringTemplate)` |Constructor | From e99ca46ff1201e30c56daafcef8aec46e4f59f57 Mon Sep 17 00:00:00 2001 From: mbsoftlab Date: Wed, 30 Dec 2020 20:16:38 +0100 Subject: [PATCH 02/28] TE-8 Extract interface for TemplateEngine (ITemplateEngine) --- .../ITemplateEngine.cs | 19 ++++++++ .../TemplateEngine.cs | 44 ++++++++++--------- 2 files changed, 42 insertions(+), 21 deletions(-) create mode 100644 MbSoftLab.TemplateEngine.Core/ITemplateEngine.cs diff --git a/MbSoftLab.TemplateEngine.Core/ITemplateEngine.cs b/MbSoftLab.TemplateEngine.Core/ITemplateEngine.cs new file mode 100644 index 0000000..efe3271 --- /dev/null +++ b/MbSoftLab.TemplateEngine.Core/ITemplateEngine.cs @@ -0,0 +1,19 @@ +using System.Globalization; + +namespace MbSoftLab.TemplateEngine.Core +{ + public interface ITemplateEngine + { + string CloseingDelimiter { get; set; } + ITemplateEngineConfig Config { get; set; } + CultureInfo CultureInfo { get; set; } + string NullStringValue { get; set; } + string OpeningDelimiter { get; set; } + T TemplateDataModel { get; set; } + string TemplateString { get; set; } + + string CreateStringFromTemplate(string stringTemplate = null); + string CreateStringFromTemplate(T templateDataModel); + string CreateStringFromTemplate(T templateDataModel, string stringTemplate); + } +} \ No newline at end of file diff --git a/MbSoftLab.TemplateEngine.Core/TemplateEngine.cs b/MbSoftLab.TemplateEngine.Core/TemplateEngine.cs index e223663..0b5e5ed 100644 --- a/MbSoftLab.TemplateEngine.Core/TemplateEngine.cs +++ b/MbSoftLab.TemplateEngine.Core/TemplateEngine.cs @@ -9,7 +9,7 @@ namespace MbSoftLab.TemplateEngine.Core /// A simple StringTemplateengine for .NET.

/// See
for more details ///
- public class TemplateEngine : TemplateEngine + public class TemplateEngine : TemplateEngine,ITemplateEngine { #region --- CONSTRUCTORS public TemplateEngine(object templateDataModel, string stringTemplate):base(templateDataModel, stringTemplate) @@ -27,22 +27,22 @@ public TemplateEngine() } #endregion } - - public class TemplateEngine + + public class TemplateEngine : ITemplateEngine { private string _outputString; - + #region --- PUBLIC PROPERTYS /// /// Beginning Char for a PlaceholderProperty. The Defaultvalue ist "${". /// - public string OpeningDelimiter { get=>_openingDelimiter; set=>_openingDelimiter=value.Trim(); } + public string OpeningDelimiter { get => _openingDelimiter; set => _openingDelimiter = value.Trim(); } private string _openingDelimiter = "${"; /// /// Ending Char for a PlaceholderProperty. Der Default ist "}". /// - public string CloseingDelimiter { get=>_closeingDelimiter; set=>_closeingDelimiter=value.Trim(); } - private string _closeingDelimiter = "}"; + public string CloseingDelimiter { get => _closeingDelimiter; set => _closeingDelimiter = value.Trim(); } + private string _closeingDelimiter = "}"; /// /// Model with propertys to fill ${PlaceholderPropertys} in the template. The propertynames at DataModel has to be equal with ${Placeholder} /// @@ -54,7 +54,8 @@ public class TemplateEngine public string TemplateString { get => _templateString; - set { + set + { if (value != null && value != _templateString) _templateString = value; } @@ -63,13 +64,14 @@ public string TemplateString /// /// Get or Set the string for NULL-Values. Default = NULL. /// - public string NullStringValue { get=>_nullStringValue; set=>_nullStringValue=value; } + public string NullStringValue { get => _nullStringValue; set => _nullStringValue = value; } string _nullStringValue = "NULL"; public CultureInfo CultureInfo { get; set; } = CultureInfo.CreateSpecificCulture("en-US"); - public ITemplateEngineConfig Config { - get=>_config; - set + public ITemplateEngineConfig Config + { + get => _config; + set { _config = value; this.NullStringValue = _config.NullStringValue; @@ -78,7 +80,7 @@ public ITemplateEngineConfig Config { this.TemplateDataModel = _config.TemplateDataModel; this.TemplateString = _config.TemplateString; this.CultureInfo = _config.CultureInfo; - } + } } private ITemplateEngineConfig _config; #endregion @@ -94,14 +96,14 @@ public TemplateEngine(T templateDataModel) { _templateDataModel = templateDataModel; } - + public TemplateEngine() { } - + #endregion - + /// /// Replaces all Propertys of templateDataModel in stringTemplate. The Popertynames from templateDataModel a the name of ${Placeholder} have to be equal. /// Example: public string MyProperty => ${MyProperty} @@ -111,14 +113,14 @@ public string CreateStringFromTemplate(string stringTemplate = null) { try { - TemplateString = stringTemplate; - return CreateStringFromTemplate(); + TemplateString = stringTemplate; + return CreateStringFromTemplate(); } catch (Exception ex) { throw ex; } - + } /// /// Replaces all Propertys of templateDataModel in stringTemplate. The Popertynames from templateDataModel a the name of ${Placeholder} have to be equal. @@ -149,8 +151,8 @@ public string CreateStringFromTemplate(T templateDataModel) /// File with Data from TemplateDataModel private string CreateStringFromTemplate() { - _outputString=_templateString; - + _outputString = _templateString; + IPlaceholderValueRaplacer placeholderValueRaplacer = new PlaceholderValueRaplacer(_outputString, _nullStringValue); placeholderValueRaplacer.CultureInfo = CultureInfo; TemplateDataModelProcessor templateDataModelProcessor = new TemplateDataModelProcessor(_openingDelimiter, _closeingDelimiter, placeholderValueRaplacer); From 08bb27a1f723777f4d598af1bb1377d1dcf94bc8 Mon Sep 17 00:00:00 2001 From: mbsoftlab Date: Wed, 30 Dec 2020 23:08:09 +0100 Subject: [PATCH 03/28] TE-13 Implemented wrapper for RazorEngineCore (first runable version) --- MbSoftLab.TemplateEngine.Core.sln | 22 ++++++++ .../Documentation.xml | 4 +- .../MbSoftLab.TemplateEngine.Core.csproj | 4 ++ .../RazorTemplateEngine.cs | 50 +++++++++++++++++ .../TemplateDataModel.cs | 9 ++++ .../TemplateEngine.cs | 2 +- .../TemplateEngineExtensions.cs | 4 +- .../MbSoftlab.TemplateEngine.Core.Demo.csproj | 21 ++++++++ MbSoftlab.TemplateEngine.Core.Demo/Person.cs | 33 ++++++++++++ MbSoftlab.TemplateEngine.Core.Demo/Program.cs | 54 +++++++++++++++++++ .../TestModel.cshtml | 26 +++++++++ 11 files changed, 224 insertions(+), 5 deletions(-) create mode 100644 MbSoftLab.TemplateEngine.Core/RazorTemplateEngine.cs create mode 100644 MbSoftLab.TemplateEngine.Core/TemplateDataModel.cs create mode 100644 MbSoftlab.TemplateEngine.Core.Demo/MbSoftlab.TemplateEngine.Core.Demo.csproj create mode 100644 MbSoftlab.TemplateEngine.Core.Demo/Person.cs create mode 100644 MbSoftlab.TemplateEngine.Core.Demo/Program.cs create mode 100644 MbSoftlab.TemplateEngine.Core.Demo/TestModel.cshtml diff --git a/MbSoftLab.TemplateEngine.Core.sln b/MbSoftLab.TemplateEngine.Core.sln index 5370e98..aa7f849 100644 --- a/MbSoftLab.TemplateEngine.Core.sln +++ b/MbSoftLab.TemplateEngine.Core.sln @@ -7,6 +7,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MbSoftLab.TemplateEngine.Co EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MbSoftLab.TemplateEngine.Core", "MbSoftLab.TemplateEngine.Core\MbSoftLab.TemplateEngine.Core.csproj", "{CA5BFFAC-ADA4-478B-8B13-B3AF81FE4A05}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MbSoftlab.TemplateEngine.Core.Demo", "MbSoftlab.TemplateEngine.Core.Demo\MbSoftlab.TemplateEngine.Core.Demo.csproj", "{159ED0CF-FB05-4F88-A442-90890814E6A8}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -61,6 +63,26 @@ Global {CA5BFFAC-ADA4-478B-8B13-B3AF81FE4A05}.Release|x64.Build.0 = Release|Any CPU {CA5BFFAC-ADA4-478B-8B13-B3AF81FE4A05}.Release|x86.ActiveCfg = Release|Any CPU {CA5BFFAC-ADA4-478B-8B13-B3AF81FE4A05}.Release|x86.Build.0 = Release|Any CPU + {159ED0CF-FB05-4F88-A442-90890814E6A8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {159ED0CF-FB05-4F88-A442-90890814E6A8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {159ED0CF-FB05-4F88-A442-90890814E6A8}.Debug|ARM.ActiveCfg = Debug|Any CPU + {159ED0CF-FB05-4F88-A442-90890814E6A8}.Debug|ARM.Build.0 = Debug|Any CPU + {159ED0CF-FB05-4F88-A442-90890814E6A8}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {159ED0CF-FB05-4F88-A442-90890814E6A8}.Debug|ARM64.Build.0 = Debug|Any CPU + {159ED0CF-FB05-4F88-A442-90890814E6A8}.Debug|x64.ActiveCfg = Debug|Any CPU + {159ED0CF-FB05-4F88-A442-90890814E6A8}.Debug|x64.Build.0 = Debug|Any CPU + {159ED0CF-FB05-4F88-A442-90890814E6A8}.Debug|x86.ActiveCfg = Debug|Any CPU + {159ED0CF-FB05-4F88-A442-90890814E6A8}.Debug|x86.Build.0 = Debug|Any CPU + {159ED0CF-FB05-4F88-A442-90890814E6A8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {159ED0CF-FB05-4F88-A442-90890814E6A8}.Release|Any CPU.Build.0 = Release|Any CPU + {159ED0CF-FB05-4F88-A442-90890814E6A8}.Release|ARM.ActiveCfg = Release|Any CPU + {159ED0CF-FB05-4F88-A442-90890814E6A8}.Release|ARM.Build.0 = Release|Any CPU + {159ED0CF-FB05-4F88-A442-90890814E6A8}.Release|ARM64.ActiveCfg = Release|Any CPU + {159ED0CF-FB05-4F88-A442-90890814E6A8}.Release|ARM64.Build.0 = Release|Any CPU + {159ED0CF-FB05-4F88-A442-90890814E6A8}.Release|x64.ActiveCfg = Release|Any CPU + {159ED0CF-FB05-4F88-A442-90890814E6A8}.Release|x64.Build.0 = Release|Any CPU + {159ED0CF-FB05-4F88-A442-90890814E6A8}.Release|x86.ActiveCfg = Release|Any CPU + {159ED0CF-FB05-4F88-A442-90890814E6A8}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/MbSoftLab.TemplateEngine.Core/Documentation.xml b/MbSoftLab.TemplateEngine.Core/Documentation.xml index 4d0663d..65d356a 100644 --- a/MbSoftLab.TemplateEngine.Core/Documentation.xml +++ b/MbSoftLab.TemplateEngine.Core/Documentation.xml @@ -84,12 +84,12 @@ - + Load the TemplateDataModel from JSON and builds a String with this Data - + Loads a Templatestring from File diff --git a/MbSoftLab.TemplateEngine.Core/MbSoftLab.TemplateEngine.Core.csproj b/MbSoftLab.TemplateEngine.Core/MbSoftLab.TemplateEngine.Core.csproj index bff15ab..87e226d 100644 --- a/MbSoftLab.TemplateEngine.Core/MbSoftLab.TemplateEngine.Core.csproj +++ b/MbSoftLab.TemplateEngine.Core/MbSoftLab.TemplateEngine.Core.csproj @@ -30,4 +30,8 @@ + + + + diff --git a/MbSoftLab.TemplateEngine.Core/RazorTemplateEngine.cs b/MbSoftLab.TemplateEngine.Core/RazorTemplateEngine.cs new file mode 100644 index 0000000..2e589db --- /dev/null +++ b/MbSoftLab.TemplateEngine.Core/RazorTemplateEngine.cs @@ -0,0 +1,50 @@ +using RazorEngineCore; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Text; + +namespace MbSoftLab.TemplateEngine.Core +{ + public class RazorTemplateEngine : ITemplateEngine where T: TemplateDataModel + { + public string CloseingDelimiter { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + public ITemplateEngineConfig Config { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + public CultureInfo CultureInfo { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + public string NullStringValue { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + public string OpeningDelimiter { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + public T TemplateDataModel { get; set; } + public string TemplateString { get ; set ; } + IRazorEngine razorEngine; + public RazorTemplateEngine(IRazorEngine razorEngine) + { + this.razorEngine = razorEngine; + } + public RazorTemplateEngine() + { + razorEngine = new RazorEngine(); + } + public string CreateStringFromTemplate(string csHtmlTemplate = null) + { + TemplateString = csHtmlTemplate ?? TemplateString; + IRazorEngineCompiledTemplate template = razorEngine.Compile(TemplateString); + + string result = template.Run(TemplateDataModel); + return result; + } + + public string CreateStringFromTemplate(T templateDataModel) + { + TemplateDataModel = templateDataModel; + return CreateStringFromTemplate(); + + } + + public string CreateStringFromTemplate(T templateDataModel, string csHtmlTemplate) + { + TemplateDataModel = templateDataModel; + TemplateString = csHtmlTemplate; + return CreateStringFromTemplate(); + } + } +} diff --git a/MbSoftLab.TemplateEngine.Core/TemplateDataModel.cs b/MbSoftLab.TemplateEngine.Core/TemplateDataModel.cs new file mode 100644 index 0000000..c057626 --- /dev/null +++ b/MbSoftLab.TemplateEngine.Core/TemplateDataModel.cs @@ -0,0 +1,9 @@ +using RazorEngineCore; + +namespace MbSoftLab.TemplateEngine.Core +{ + public class TemplateDataModel : RazorEngineTemplateBase + { + + } +} diff --git a/MbSoftLab.TemplateEngine.Core/TemplateEngine.cs b/MbSoftLab.TemplateEngine.Core/TemplateEngine.cs index 0b5e5ed..52ed870 100644 --- a/MbSoftLab.TemplateEngine.Core/TemplateEngine.cs +++ b/MbSoftLab.TemplateEngine.Core/TemplateEngine.cs @@ -9,7 +9,7 @@ namespace MbSoftLab.TemplateEngine.Core /// A simple StringTemplateengine for .NET.

/// See for more details ///
- public class TemplateEngine : TemplateEngine,ITemplateEngine + public class TemplateEngine : TemplateEngine, ITemplateEngine { #region --- CONSTRUCTORS public TemplateEngine(object templateDataModel, string stringTemplate):base(templateDataModel, stringTemplate) diff --git a/MbSoftLab.TemplateEngine.Core/TemplateEngineExtensions.cs b/MbSoftLab.TemplateEngine.Core/TemplateEngineExtensions.cs index f23cd00..709c5d5 100644 --- a/MbSoftLab.TemplateEngine.Core/TemplateEngineExtensions.cs +++ b/MbSoftLab.TemplateEngine.Core/TemplateEngineExtensions.cs @@ -7,7 +7,7 @@ public static class TemplateEngineExtensions /// /// Load the TemplateDataModel from JSON and builds a String with this Data /// - public static string CreateStringFromTemplateWithJson(this TemplateEngine templateEngine, string jsonData) + public static string CreateStringFromTemplateWithJson(this ITemplateEngine templateEngine, string jsonData) { templateEngine.TemplateDataModel = JsonSerializer.Deserialize(jsonData); return templateEngine.CreateStringFromTemplate(); @@ -16,7 +16,7 @@ public static string CreateStringFromTemplateWithJson(this TemplateEngine /// Loads a Templatestring from File /// /// Path to File with Templatestring. - public static void LoadTemplateFromFile(this TemplateEngine templateEngine, string path) + public static void LoadTemplateFromFile(this ITemplateEngine templateEngine, string path) { templateEngine.TemplateString = System.IO.File.ReadAllText(path); } diff --git a/MbSoftlab.TemplateEngine.Core.Demo/MbSoftlab.TemplateEngine.Core.Demo.csproj b/MbSoftlab.TemplateEngine.Core.Demo/MbSoftlab.TemplateEngine.Core.Demo.csproj new file mode 100644 index 0000000..ad4d8f4 --- /dev/null +++ b/MbSoftlab.TemplateEngine.Core.Demo/MbSoftlab.TemplateEngine.Core.Demo.csproj @@ -0,0 +1,21 @@ + + + + Exe + netcoreapp3.1 + RazorSdk + true + true + + + + + + + + + Always + + + + diff --git a/MbSoftlab.TemplateEngine.Core.Demo/Person.cs b/MbSoftlab.TemplateEngine.Core.Demo/Person.cs new file mode 100644 index 0000000..cea1cea --- /dev/null +++ b/MbSoftlab.TemplateEngine.Core.Demo/Person.cs @@ -0,0 +1,33 @@ +using RazorEngineCore; +using System.Collections.Generic; + +namespace MbSoftLab.TemplateEngine.Core.Demo +{ + + + public class Person: TemplateDataModel + { + public string FirstName { get; set; } + public string LastName { get; set; } + public List Tags { get; set; } + public Address Address { get; set; } + public List Orders { get; set; } + + } + public class Address + { + public string Street { get; set; } + public string PostCode { get; set; } + } + public class Order + { + public int Id { get; set; } + public List Products { get; set; } + } + public class Product + { + public string ProductName { get; set; } + public float Price { get; set; } + + } +} diff --git a/MbSoftlab.TemplateEngine.Core.Demo/Program.cs b/MbSoftlab.TemplateEngine.Core.Demo/Program.cs new file mode 100644 index 0000000..99ba2b1 --- /dev/null +++ b/MbSoftlab.TemplateEngine.Core.Demo/Program.cs @@ -0,0 +1,54 @@ +using MbSoftLab.TemplateEngine.Core; +using System; +using System.Collections.Generic; + +namespace MbSoftLab.TemplateEngine.Core.Demo +{ + class Program + { + static void Main(string[] args) + { + Person testModel = new Person() + { + FirstName = "Justin", + LastName = "LastName", + Tags = new List() { "Tag1", "Tag2", "Tag3" }, + Address=new Address() + { + Street="Straße", + PostCode="7872" + }, + Orders=new List() + { + new Order() + { + Id=1, + Products=new List() + { + new Product() + { + ProductName="Product1", + Price=150 + }, + new Product() + { + ProductName="Product2", + Price=50 + } + } + } + } + + }; + + + ITemplateEngine templateEngine = new RazorTemplateEngine(); + templateEngine.LoadTemplateFromFile("TestModel.cshtml"); + Console.WriteLine(templateEngine.CreateStringFromTemplate(testModel)); + + Console.ReadLine(); + + + } + } +} diff --git a/MbSoftlab.TemplateEngine.Core.Demo/TestModel.cshtml b/MbSoftlab.TemplateEngine.Core.Demo/TestModel.cshtml new file mode 100644 index 0000000..44081e0 --- /dev/null +++ b/MbSoftlab.TemplateEngine.Core.Demo/TestModel.cshtml @@ -0,0 +1,26 @@ +@inherits MbSoftLab.TemplateEngine.Core.Demo.Person + +Hello @Model.FirstName + +

Your tags are

+@foreach (string tag in Model.Tags) +{ +

@tag

+} + +

You made this this Orders

+ +@foreach (var order in Model.Orders) +{ + + OderId: @order.Id + + Products: + @foreach (var product in order.Products) + { + Name: @product.ProductName + Preis: @product.Price + } + + +} \ No newline at end of file From 319ae1a2166f70078c6a915196dfca0cd81cc1bc Mon Sep 17 00:00:00 2001 From: mbsoftlab Date: Wed, 30 Dec 2020 23:58:39 +0100 Subject: [PATCH 04/28] Add RecursionTest() Method in cshtml --- .../TestModel.cshtml | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/MbSoftlab.TemplateEngine.Core.Demo/TestModel.cshtml b/MbSoftlab.TemplateEngine.Core.Demo/TestModel.cshtml index 44081e0..88c7e33 100644 --- a/MbSoftlab.TemplateEngine.Core.Demo/TestModel.cshtml +++ b/MbSoftlab.TemplateEngine.Core.Demo/TestModel.cshtml @@ -1,5 +1,4 @@ @inherits MbSoftLab.TemplateEngine.Core.Demo.Person - Hello @Model.FirstName

Your tags are

@@ -23,4 +22,22 @@ Hello @Model.FirstName } +} + + + +@{ RecursionTest(3); } + + +@{ + void RecursionTest(int level) + { + if (level <= 0) + { + return; + } + +
LEVEL: @level
+ @{ RecursionTest(level - 1); } + } } \ No newline at end of file From f066ac2777681471fe1edab495a7c4eb5c573b29 Mon Sep 17 00:00:00 2001 From: mbsoftlab Date: Thu, 31 Dec 2020 01:47:52 +0100 Subject: [PATCH 05/28] TE-13 Added UnitTests for RazorTemplateEngine --- .../RazorTemplateEngineUnitTest.cs | 320 ++++++++++++++++++ .../TemplateDataModelDummy.cs | 5 +- .../TemplateDataModelDummyWithList.cs | 5 +- .../TemplateDataModelDummyWithMethods.cs | 6 +- .../MbSoftLab.TemplateEngine.Core.csproj | 6 +- .../RazorTemplateEngine.cs | 48 ++- .../TemplateDataModel.cs | 4 +- .../TemplateDataModelProcessor.cs | 10 +- .../TemplateEngineConfig.cs | 5 +- MbSoftlab.TemplateEngine.Core.Demo/Person.cs | 4 +- .../TestModel.cshtml | 5 +- 11 files changed, 392 insertions(+), 26 deletions(-) create mode 100644 MbSoftLab.TemplateEngine.Core.Tests/RazorTemplateEngineUnitTest.cs diff --git a/MbSoftLab.TemplateEngine.Core.Tests/RazorTemplateEngineUnitTest.cs b/MbSoftLab.TemplateEngine.Core.Tests/RazorTemplateEngineUnitTest.cs new file mode 100644 index 0000000..d0d3eb8 --- /dev/null +++ b/MbSoftLab.TemplateEngine.Core.Tests/RazorTemplateEngineUnitTest.cs @@ -0,0 +1,320 @@ +using MbSoftLab.TemplateEngine.Core; +using NUnit.Framework; +using System; +using System.Globalization; +using System.IO; + +namespace TemplateEngineCore.Tests +{ + + [TestFixture] + public class RazorTemplateEngineUnitTest : UnitTestBase + { + + [Test] + public void can_create_a_valid_string_from_template() + { + //Arrange + var sut = new RazorTemplateEngine(GetTemplateDataModelDummy(), "@Model.DummyStringProp1"); //SUT = [S]ystem [U]nder [T]est + string expectedReturnString = "DummyStringProp1Value"; + + //Act Ausführen der zu testenden Funktion + string returnString = sut.CreateStringFromTemplate(); + + //Assert + Assert.AreEqual(expectedReturnString, returnString); + } + [Test] + public void can_create_a_valid_string_from_template_with_json() + { + //Arrange + var sut = new RazorTemplateEngine(); //SUT = [S]ystem [U]nder [T]est + sut.TemplateString = "@Model.DummyStringProp1"; + string expectedReturnString = "DummyStringProp1Value"; + string jsonData = GetDummyJson(); + + //Act Ausführen der zu testenden Funktion + string returnString = sut.CreateStringFromTemplateWithJson(jsonData); + + //Assert + Assert.AreEqual(expectedReturnString, returnString); + } + [Test] + public void can_handle_null_Values_in_Propertys() + { + //Arrange + var sut = new RazorTemplateEngine(GetTemplateDataModelDummy(), "@Model.DummyStringProp2"); //SUT = [S]ystem [U]nder [T]est + string expectedReturnString = ""; + + //Act Ausführen der zu testenden Funktion + string returnString = sut.CreateStringFromTemplate(); + + //Assert + Assert.AreEqual(expectedReturnString, returnString); + } + [Test] + public void can_set_a_custom_null_value_String() + { + //Arrange + var sut = new RazorTemplateEngine(GetTemplateDataModelDummy(), "@Model.DummyStringProp2"); //SUT = [S]ystem [U]nder [T]est + sut.NullStringValue = "Nothing"; + string expectedReturnString = "Nothing"; + + //Act + string returnString = sut.CreateStringFromTemplate(); + + //Assert + Assert.AreEqual(expectedReturnString, returnString); + } + [Test] + public void can_set_a_template() + { + //Arrange + var sut = new RazorTemplateEngine(GetTemplateDataModelDummy(), "@Model.DummyStringProp2"); //SUT = [S]ystem [U]nder [T]est + sut.NullStringValue = ""; + sut.TemplateString = "@Model.DummyStringProp2"; + string expectedReturnString = ""; + + //Act + string returnString = sut.CreateStringFromTemplate(); + + //Assert + Assert.AreEqual(expectedReturnString, returnString); + } + [Test] + public void can_use_the_config() + { + //Arrange + + TemplateEngineConfig templateEngineConfig = new TemplateEngineConfig() + { + OpeningDelimiter = "{{", + CloseingDelimiter = "}}", + NullStringValue = "---", + TemplateDataModel = GetTemplateDataModelDummy(), + TemplateString = "@Model.DummyStringProp2" + }; + var sut = new RazorTemplateEngine(); //SUT = [S]ystem [U]nder [T]est + sut.Config = templateEngineConfig; + + string expectedReturnString = ""; + + //Act + string returnString = sut.CreateStringFromTemplate(); + + //Assert + Assert.AreEqual(expectedReturnString, returnString); + } + [Test] + public void can_use_the_generic_config() + { + //Arrange + + TemplateEngineConfig templateEngineConfig = new TemplateEngineConfig() + { + OpeningDelimiter = "{{", + CloseingDelimiter = "}}", + NullStringValue = "", + TemplateDataModel = GetTemplateDataModelDummy(), + TemplateString = "@Model.DummyStringProp2" + }; + var sut = new RazorTemplateEngine(); + sut.Config = templateEngineConfig; + + string expectedReturnString = ""; + + //Act + string returnString = sut.CreateStringFromTemplate(); + + //Assert + Assert.AreEqual(expectedReturnString, returnString); + } + [Test] + public void can_set_a_template_and_model_on_creating() + { + //Arrange + var sut = new RazorTemplateEngine(); + sut.NullStringValue = ""; + string expectedReturnString = ""; + + //Act + string returnString = sut.CreateStringFromTemplate(GetTemplateDataModelDummy(), "@Model.DummyStringProp2"); + + //Assert + Assert.AreEqual(expectedReturnString, returnString); + } + [Test] + public void can_set_a_model_on_creating() + { + //Arrange + var sut = new RazorTemplateEngine(); + sut.NullStringValue = ""; + sut.TemplateString = "@Model.DummyStringProp2"; + string expectedReturnString = ""; + + //Act + string returnString = sut.CreateStringFromTemplate(GetTemplateDataModelDummy()); + + //Assert + Assert.AreEqual(expectedReturnString, returnString); + } + + + + [Test] + public void throws_excepton_if_file_load_fail() + { + //Arrange + var sut = new RazorTemplateEngine(GetTemplateDataModelDummy(), "@Model.DummyObjectProp1"); //SUT = [S]ystem [U]nder [T]est + + //Assert + Assert.Throws(delegate + { + + //Act + sut.LoadTemplateFromFile("NonExistingFile.txt"); + }); + } + [Test] + public void can_handle_a_DataModel_with_a_list_property() + { + //Arrange + var sut = new RazorTemplateEngine(GetTemplateDataModelDummyWithListAndMethod(), "@Model.DummyStringListProp2"); //SUT = [S]ystem [U]nder [T]est + //Act / Assert + Assert.DoesNotThrow(delegate { sut.CreateStringFromTemplate(); }); + + } + [Test] + public void can_handle_a_Method_in_DataModel_without_Exeption() + { + //Arrange + var sut = new RazorTemplateEngine(GetTemplateDataModelDummyWithListAndMethod(), "@Model.StringReturningMethod()"); //SUT = [S]ystem [U]nder [T]est + Assert.DoesNotThrow(delegate { sut.CreateStringFromTemplate(); }); + } + [Test] + [TestCase("StringReturningMethod()", "StringReturnValue")] + [TestCase("BoolReturningMethod()", "True")] + public void can_handle_return_values_from_a_method(string methodName, string returnValue) + { + //Arrange + var sut = new RazorTemplateEngine(GetTemplateDataModelDummyWithMethods(), "@Model." + methodName + ""); //SUT = [S]ystem [U]nder [T]est + + string expectedReturnString = "" + returnValue + ""; + + //Act + string returnString = sut.CreateStringFromTemplate(); + + //Assert + Assert.AreEqual(expectedReturnString, returnString); + } + [TestCase] + public void can_handle_return_values_from_IntReturningMethod() + { + //Arrange + string methodName = "IntReturningMethod()"; + string returnValue = Convert.ToString(Convert.ToInt32("12")); + var sut = new RazorTemplateEngine(GetTemplateDataModelDummyWithMethods(), "@Model." + methodName + ""); //SUT = [S]ystem [U]nder [T]est + + string expectedReturnString = "" + returnValue + ""; + + //Act + string returnString = sut.CreateStringFromTemplate(); + + //Assert + Assert.AreEqual(expectedReturnString, returnString); + } + [TestCase] + public void can_handle_return_values_from_DoubleReturningMethod() + { + //Arrange + string methodName = "DoubleReturningMethod()"; + double value = 1.2; + string returnValue = Convert.ToString(value); + var sut = new RazorTemplateEngine(GetTemplateDataModelDummyWithMethods(), "@Model." + methodName + ""); //SUT = [S]ystem [U]nder [T]est + + string expectedReturnString = "" + returnValue + ""; + + //Act + string returnString = sut.CreateStringFromTemplate(); + + //Assert + Assert.AreEqual(expectedReturnString, returnString); + } + [Test] + [TestCase("DummyByteProp", "255")] + [TestCase("DummySByteProp", "-5")] + [TestCase("DummyCharProp", "c")] + [TestCase("DummyUInt16", "8")] + [TestCase("DummyInt16", "-8")] + [TestCase("DummyIntProp1", "1")] + [TestCase("DummyInt64Prop", "1234567")] + [TestCase("DummyDecimalProp", "55")] + [TestCase("DummBoolProp1", "True")] + [TestCase("DummyBoolQProp1", "True")]// Bool With Null + [TestCase("DummyBoolProp2", "False")] + [TestCase("DummyBoolQProp2", "")] + //[TestCase("DummyDoubleProp1", "1.75")] + public void can_handle_values_from_propertys(string propertyName, string expectedOutput) + { + //Arrange + var sut = new RazorTemplateEngine(GetTemplateDataModelDummy(), "@Model." + propertyName + ""); //SUT = [S]ystem [U]nder [T]est + string expectedReturnString = "" + expectedOutput + ""; + + //Act + string returnString = sut.CreateStringFromTemplate(); + + //Assert + Assert.AreEqual(expectedReturnString, returnString); + } + [TestCase] + public void can_handle_double_values_from_propertys() + { + //Arrange + string propertyName = "DummyDoubleProp1"; + double value = 1.75; + string expectedOutput = Convert.ToString(value); + var sut = new RazorTemplateEngine(GetTemplateDataModelDummy(), "@Model." + propertyName + ""); //SUT = [S]ystem [U]nder [T]est + string expectedReturnString = "" + expectedOutput + ""; + + //Act + string returnString = sut.CreateStringFromTemplate(); + + //Assert + Assert.AreEqual(expectedReturnString, returnString); + } + [TestCase] + public void can_handle_date_values_from_propertys() + { + string propertyName = "DummyDateTimeProp1"; + string expectedOutput = Convert.ToString(Convert.ToDateTime("01.01.2020 00:00:00")); + + //Arrange -> Vorbereiten der Testumgebung und der benötigten Prameter + var sut = new RazorTemplateEngine(GetTemplateDataModelDummy(), "@Model." + propertyName + ""); //SUT = [S]ystem [U]nder [T]est + + string expectedReturnString = "" + expectedOutput + ""; + + //Act Ausführen der zu testenden Funktion + string returnString = sut.CreateStringFromTemplate(); + + //Assert Prüfen der Ergebnisse + Assert.AreEqual(expectedReturnString, returnString); + } + [TestCase] + public void can_create_and_use_SpecificCulture() + { + //Arrange + string propertyName = "DummyDoubleProp1"; + double value = 1.75; + string expectedOutput = Convert.ToString(value, CultureInfo.CreateSpecificCulture("de-DE")); + var sut = new RazorTemplateEngine(GetTemplateDataModelDummy(), "@Model." + propertyName + ""); + sut.CultureInfo = CultureInfo.CreateSpecificCulture("de-DE"); + string expectedReturnString = "" + expectedOutput + ""; + + //Act + string returnString = sut.CreateStringFromTemplate(); + + //Assert + Assert.AreEqual(expectedReturnString, returnString); + } + } +} \ No newline at end of file diff --git a/MbSoftLab.TemplateEngine.Core.Tests/TemplateDataModelDummy.cs b/MbSoftLab.TemplateEngine.Core.Tests/TemplateDataModelDummy.cs index a31cedb..6cca360 100644 --- a/MbSoftLab.TemplateEngine.Core.Tests/TemplateDataModelDummy.cs +++ b/MbSoftLab.TemplateEngine.Core.Tests/TemplateDataModelDummy.cs @@ -1,8 +1,9 @@ -using System; +using MbSoftLab.TemplateEngine.Core; +using System; namespace TemplateEngineCore.Tests { - public class TemplateDataModelDummy + public class TemplateDataModelDummy:TemplateDataModel { public string DummyStringProp1 { get; set; } diff --git a/MbSoftLab.TemplateEngine.Core.Tests/TemplateDataModelDummyWithList.cs b/MbSoftLab.TemplateEngine.Core.Tests/TemplateDataModelDummyWithList.cs index 3db4285..c152eac 100644 --- a/MbSoftLab.TemplateEngine.Core.Tests/TemplateDataModelDummyWithList.cs +++ b/MbSoftLab.TemplateEngine.Core.Tests/TemplateDataModelDummyWithList.cs @@ -1,8 +1,9 @@ -using System.Collections.Generic; +using MbSoftLab.TemplateEngine.Core; +using System.Collections.Generic; namespace TemplateEngineCore.Tests { - public class TemplateDataModelDummyWithList + public class TemplateDataModelDummyWithList:TemplateDataModel { public string DummyStringProp1 { get; set; } public List DummyStringListProp2 { get; set; } diff --git a/MbSoftLab.TemplateEngine.Core.Tests/TemplateDataModelDummyWithMethods.cs b/MbSoftLab.TemplateEngine.Core.Tests/TemplateDataModelDummyWithMethods.cs index ee14e74..da1ec14 100644 --- a/MbSoftLab.TemplateEngine.Core.Tests/TemplateDataModelDummyWithMethods.cs +++ b/MbSoftLab.TemplateEngine.Core.Tests/TemplateDataModelDummyWithMethods.cs @@ -1,6 +1,8 @@ -namespace TemplateEngineCore.Tests +using MbSoftLab.TemplateEngine.Core; + +namespace TemplateEngineCore.Tests { - public class TemplateDataModelDummyWithMethods + public class TemplateDataModelDummyWithMethods:TemplateDataModel { public string StringReturningMethod() diff --git a/MbSoftLab.TemplateEngine.Core/MbSoftLab.TemplateEngine.Core.csproj b/MbSoftLab.TemplateEngine.Core/MbSoftLab.TemplateEngine.Core.csproj index 87e226d..fd6eaf1 100644 --- a/MbSoftLab.TemplateEngine.Core/MbSoftLab.TemplateEngine.Core.csproj +++ b/MbSoftLab.TemplateEngine.Core/MbSoftLab.TemplateEngine.Core.csproj @@ -2,10 +2,10 @@ netcoreapp3.1 - 1.0.8.0 - 1.0.8.0 + 1.0.8.1 + 1.0.8.1 1.0.8 - 1.0.8-preview + 1.0.8-preview2 This StringTemplateEngine can replace values from Classpropertys and methods in stringtemplates Documentation.xml true diff --git a/MbSoftLab.TemplateEngine.Core/RazorTemplateEngine.cs b/MbSoftLab.TemplateEngine.Core/RazorTemplateEngine.cs index 2e589db..0e5ae59 100644 --- a/MbSoftLab.TemplateEngine.Core/RazorTemplateEngine.cs +++ b/MbSoftLab.TemplateEngine.Core/RazorTemplateEngine.cs @@ -1,18 +1,48 @@ using RazorEngineCore; using System; using System.Collections.Generic; +using System.ComponentModel; using System.Globalization; using System.Text; namespace MbSoftLab.TemplateEngine.Core { - public class RazorTemplateEngine : ITemplateEngine where T: TemplateDataModel + public class RazorTemplateEngine : ITemplateEngine where T: TemplateDataModel { - public string CloseingDelimiter { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - public ITemplateEngineConfig Config { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - public CultureInfo CultureInfo { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - public string NullStringValue { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - public string OpeningDelimiter { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + public string CloseingDelimiter { get { Console.WriteLine($"RazorTemplateEngine has no {nameof(CloseingDelimiter)}"); return ""; } set => Console.WriteLine($"Can not set {nameof(CloseingDelimiter)} for RazorTemplateEngine"); } + ITemplateEngineConfig _config; + public ITemplateEngineConfig Config + { + get => _config; + set + { + _config = value; + this.NullStringValue = _config.NullStringValue; + this.OpeningDelimiter = _config.OpeningDelimiter; + this.CloseingDelimiter = _config.CloseingDelimiter; + this.TemplateDataModel = _config.TemplateDataModel; + this.TemplateString = _config.TemplateString; + this.CultureInfo = _config.CultureInfo; + } + } + public CultureInfo CultureInfo { get { Console.WriteLine($"{nameof(RazorTemplateEngine)} can not maipulate {nameof(CultureInfo)}"); return null;} set => Console.WriteLine($"{nameof(RazorTemplateEngine)} can not maipulate {nameof(CultureInfo)}"); } + + public string NullStringValue { + get => "String.Empty"; + set {Console.WriteLine(new WarningException($"{nameof(RazorTemplateEngine)} can not maipulate {nameof(NullStringValue)}").Message);} + } + public string OpeningDelimiter + { + get + { + Console.WriteLine(new WarningException($"RazorTemplateEngine has no {nameof(OpeningDelimiter)}").Message); + return ""; + } + set + { + Console.WriteLine(new WarningException($"Can not set {nameof(OpeningDelimiter)} for RazorTemplateEngine").Message); + } + } public T TemplateDataModel { get; set; } public string TemplateString { get ; set ; } IRazorEngine razorEngine; @@ -24,6 +54,12 @@ public RazorTemplateEngine() { razorEngine = new RazorEngine(); } + public RazorTemplateEngine(T dataModel, string templateString ) + { + razorEngine = new RazorEngine(); + TemplateDataModel = dataModel; + TemplateString = templateString; + } public string CreateStringFromTemplate(string csHtmlTemplate = null) { TemplateString = csHtmlTemplate ?? TemplateString; diff --git a/MbSoftLab.TemplateEngine.Core/TemplateDataModel.cs b/MbSoftLab.TemplateEngine.Core/TemplateDataModel.cs index c057626..cb72436 100644 --- a/MbSoftLab.TemplateEngine.Core/TemplateDataModel.cs +++ b/MbSoftLab.TemplateEngine.Core/TemplateDataModel.cs @@ -2,8 +2,8 @@ namespace MbSoftLab.TemplateEngine.Core { - public class TemplateDataModel : RazorEngineTemplateBase + public class TemplateDataModel : RazorEngineTemplateBase { - + public new T Model { get; set; } } } diff --git a/MbSoftLab.TemplateEngine.Core/TemplateDataModelProcessor.cs b/MbSoftLab.TemplateEngine.Core/TemplateDataModelProcessor.cs index 3d3c410..c2360f6 100644 --- a/MbSoftLab.TemplateEngine.Core/TemplateDataModelProcessor.cs +++ b/MbSoftLab.TemplateEngine.Core/TemplateDataModelProcessor.cs @@ -13,11 +13,19 @@ class TemplateDataModelProcessor IPlaceholderValueRaplacer _placeholderValueRaplacer; + private void AddMethodsFromTemplateDataModelBaseClassToBlacklist() + { + new TemplateDataModel().GetType() + .GetMethods().ToList() + .ForEach(method=>_methodBlacklist.Add(method.Name)); + + } public TemplateDataModelProcessor(string openingDelimiter, string closeingDelimiter, IPlaceholderValueRaplacer placeholderValueRaplacer) { _openingDelimiter = openingDelimiter; _closeingDelimiter = closeingDelimiter; _placeholderValueRaplacer = placeholderValueRaplacer; + AddMethodsFromTemplateDataModelBaseClassToBlacklist(); } public void ProcessTemplateDataModell(object templateDataModel) { @@ -27,7 +35,7 @@ public void ProcessTemplateDataModell(object templateDataModel) private void ProcessTemplateDataModelClassMethods(object templateDataModel) { Type t = templateDataModel.GetType(); - List methodInfos = t.GetMethods().Where(mi => mi.IsSpecialName == false + List methodInfos = t.GetMethods().Where(mi => mi.IsSpecialName == false && !_methodBlacklist.Contains(mi.Name) ).ToList(); diff --git a/MbSoftLab.TemplateEngine.Core/TemplateEngineConfig.cs b/MbSoftLab.TemplateEngine.Core/TemplateEngineConfig.cs index a3eb4ef..7ff0d5c 100644 --- a/MbSoftLab.TemplateEngine.Core/TemplateEngineConfig.cs +++ b/MbSoftLab.TemplateEngine.Core/TemplateEngineConfig.cs @@ -1,11 +1,10 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Globalization; using System.Text; namespace MbSoftLab.TemplateEngine.Core { - + /// /// /// diff --git a/MbSoftlab.TemplateEngine.Core.Demo/Person.cs b/MbSoftlab.TemplateEngine.Core.Demo/Person.cs index cea1cea..bc204bb 100644 --- a/MbSoftlab.TemplateEngine.Core.Demo/Person.cs +++ b/MbSoftlab.TemplateEngine.Core.Demo/Person.cs @@ -3,9 +3,7 @@ namespace MbSoftLab.TemplateEngine.Core.Demo { - - - public class Person: TemplateDataModel + public class Person: TemplateDataModel { public string FirstName { get; set; } public string LastName { get; set; } diff --git a/MbSoftlab.TemplateEngine.Core.Demo/TestModel.cshtml b/MbSoftlab.TemplateEngine.Core.Demo/TestModel.cshtml index 88c7e33..199bf9a 100644 --- a/MbSoftlab.TemplateEngine.Core.Demo/TestModel.cshtml +++ b/MbSoftlab.TemplateEngine.Core.Demo/TestModel.cshtml @@ -38,6 +38,7 @@ Hello @Model.FirstName }
LEVEL: @level
- @{ RecursionTest(level - 1); } + RecursionTest(level - 1); } -} \ No newline at end of file +} + From 8339252add6fec4f906c962551ac660519d01e04 Mon Sep 17 00:00:00 2001 From: mbsoftlab Date: Thu, 31 Dec 2020 02:05:30 +0100 Subject: [PATCH 06/28] TE-3 Reformat unittests --- .../RazorTemplateEngineUnitTest.cs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/MbSoftLab.TemplateEngine.Core.Tests/RazorTemplateEngineUnitTest.cs b/MbSoftLab.TemplateEngine.Core.Tests/RazorTemplateEngineUnitTest.cs index d0d3eb8..7f7c935 100644 --- a/MbSoftLab.TemplateEngine.Core.Tests/RazorTemplateEngineUnitTest.cs +++ b/MbSoftLab.TemplateEngine.Core.Tests/RazorTemplateEngineUnitTest.cs @@ -18,7 +18,7 @@ public void can_create_a_valid_string_from_template() var sut = new RazorTemplateEngine(GetTemplateDataModelDummy(), "@Model.DummyStringProp1"); //SUT = [S]ystem [U]nder [T]est string expectedReturnString = "DummyStringProp1Value"; - //Act Ausführen der zu testenden Funktion + //Act string returnString = sut.CreateStringFromTemplate(); //Assert @@ -33,7 +33,7 @@ public void can_create_a_valid_string_from_template_with_json() string expectedReturnString = "DummyStringProp1Value"; string jsonData = GetDummyJson(); - //Act Ausführen der zu testenden Funktion + //Act string returnString = sut.CreateStringFromTemplateWithJson(jsonData); //Assert @@ -46,7 +46,7 @@ public void can_handle_null_Values_in_Propertys() var sut = new RazorTemplateEngine(GetTemplateDataModelDummy(), "@Model.DummyStringProp2"); //SUT = [S]ystem [U]nder [T]est string expectedReturnString = ""; - //Act Ausführen der zu testenden Funktion + //Act string returnString = sut.CreateStringFromTemplate(); //Assert @@ -85,7 +85,6 @@ public void can_set_a_template() public void can_use_the_config() { //Arrange - TemplateEngineConfig templateEngineConfig = new TemplateEngineConfig() { OpeningDelimiter = "{{", @@ -109,7 +108,6 @@ public void can_use_the_config() public void can_use_the_generic_config() { //Arrange - TemplateEngineConfig templateEngineConfig = new TemplateEngineConfig() { OpeningDelimiter = "{{", @@ -162,7 +160,7 @@ public void can_set_a_model_on_creating() [Test] - public void throws_excepton_if_file_load_fail() + public void throws_excepton_if_fileLoading_failed() { //Arrange var sut = new RazorTemplateEngine(GetTemplateDataModelDummy(), "@Model.DummyObjectProp1"); //SUT = [S]ystem [U]nder [T]est From 275b9ad6b2f66460446d107bf0e027eb05dbdd70 Mon Sep 17 00:00:00 2001 From: mbsoftlab Date: Thu, 31 Dec 2020 03:53:54 +0100 Subject: [PATCH 07/28] TE-13 BugFixes and add ToDos --- .../RazorTemplateEngineUnitTest.cs | 4 +- .../TemplateDataModelDummy.cs | 5 +++ .../UnitTestBase.cs | 7 ++-- .../PlaceholderValueRaplacer.cs | 40 +++++++++++++++++++ .../TemplateDataModel.cs | 7 ++++ MbSoftlab.TemplateEngine.Core.Demo/Program.cs | 10 ++++- .../TestModel.cshtml | 4 +- 7 files changed, 70 insertions(+), 7 deletions(-) diff --git a/MbSoftLab.TemplateEngine.Core.Tests/RazorTemplateEngineUnitTest.cs b/MbSoftLab.TemplateEngine.Core.Tests/RazorTemplateEngineUnitTest.cs index 7f7c935..9b4873f 100644 --- a/MbSoftLab.TemplateEngine.Core.Tests/RazorTemplateEngineUnitTest.cs +++ b/MbSoftLab.TemplateEngine.Core.Tests/RazorTemplateEngineUnitTest.cs @@ -52,11 +52,11 @@ public void can_handle_null_Values_in_Propertys() //Assert Assert.AreEqual(expectedReturnString, returnString); } - [Test] + //[Test] //ToDo: Handle Custom NullValueString for RazorTemplateEngine public void can_set_a_custom_null_value_String() { //Arrange - var sut = new RazorTemplateEngine(GetTemplateDataModelDummy(), "@Model.DummyStringProp2"); //SUT = [S]ystem [U]nder [T]est + var sut = new RazorTemplateEngine(GetTemplateDataModelDummy(), "@Model.DummyStringProp2.GetNullstringValue()"); //SUT = [S]ystem [U]nder [T]est sut.NullStringValue = "Nothing"; string expectedReturnString = "Nothing"; diff --git a/MbSoftLab.TemplateEngine.Core.Tests/TemplateDataModelDummy.cs b/MbSoftLab.TemplateEngine.Core.Tests/TemplateDataModelDummy.cs index 6cca360..d262dde 100644 --- a/MbSoftLab.TemplateEngine.Core.Tests/TemplateDataModelDummy.cs +++ b/MbSoftLab.TemplateEngine.Core.Tests/TemplateDataModelDummy.cs @@ -1,12 +1,17 @@ using MbSoftLab.TemplateEngine.Core; using System; +using System.ComponentModel.DataAnnotations; namespace TemplateEngineCore.Tests { public class TemplateDataModelDummy:TemplateDataModel { + public string DummyStringProp1 { get; set; } + + + [DisplaySetting(NullStringValue ="Nothing")] public string DummyStringProp2 { get; set; } public DateTime DummyDateTimeProp1 { get; set; } diff --git a/MbSoftLab.TemplateEngine.Core.Tests/UnitTestBase.cs b/MbSoftLab.TemplateEngine.Core.Tests/UnitTestBase.cs index 495ac5e..b912b66 100644 --- a/MbSoftLab.TemplateEngine.Core.Tests/UnitTestBase.cs +++ b/MbSoftLab.TemplateEngine.Core.Tests/UnitTestBase.cs @@ -1,4 +1,5 @@ -using NUnit.Framework; +using MbSoftLab.TemplateEngine.Core; +using NUnit.Framework; using System; using System.Collections.Generic; @@ -50,8 +51,8 @@ public TemplateDataModelDummy GetTemplateDataModelDummy() DummySByteProp = -5 }; - - return templateDataModelFake; + + return templateDataModelFake; } public string GetDummyJson() { diff --git a/MbSoftLab.TemplateEngine.Core/PlaceholderValueRaplacer.cs b/MbSoftLab.TemplateEngine.Core/PlaceholderValueRaplacer.cs index 5366c44..7a18a46 100644 --- a/MbSoftLab.TemplateEngine.Core/PlaceholderValueRaplacer.cs +++ b/MbSoftLab.TemplateEngine.Core/PlaceholderValueRaplacer.cs @@ -1,10 +1,50 @@ using System; using System.Collections.Generic; using System.Globalization; +using System.Reflection; using System.Text; namespace MbSoftLab.TemplateEngine.Core { + public class DisplaySetting : Attribute + { + private readonly string _value; + + + public string NullStringValue { get; set; } + public CultureInfo CultureInfo { get; set; } + } + public static class TemplateDataModelExtensions + { + public static string GetNullstringValue(this string value) + { + string output = null; + DisplaySetting[] attrs = GetDisplaySettingsFromTemplateDataModel(value); + + if (attrs.Length > 0) + output = attrs[0].NullStringValue; + + return output; + } + public static string ToString(this string value) + { + string output = null; + DisplaySetting[] attrs = GetDisplaySettingsFromTemplateDataModel(value); + + if (attrs.Length > 0) + output = attrs[0].NullStringValue; + + return output; + } + + private static DisplaySetting[] GetDisplaySettingsFromTemplateDataModel(string value) + { + Type type = value.GetType(); + FieldInfo fi = type.GetField(value.ToString()); + DisplaySetting[] attrs = fi.GetCustomAttributes(typeof(DisplaySetting), false) as DisplaySetting []; + return attrs; + } + } class PlaceholderValueRaplacer : IPlaceholderValueRaplacer { string _outputString; diff --git a/MbSoftLab.TemplateEngine.Core/TemplateDataModel.cs b/MbSoftLab.TemplateEngine.Core/TemplateDataModel.cs index cb72436..6c3a5b5 100644 --- a/MbSoftLab.TemplateEngine.Core/TemplateDataModel.cs +++ b/MbSoftLab.TemplateEngine.Core/TemplateDataModel.cs @@ -1,9 +1,16 @@ using RazorEngineCore; +using System.Text.Json.Serialization; namespace MbSoftLab.TemplateEngine.Core { + public class TemplateDataModel : RazorEngineTemplateBase { + [JsonIgnore] public new T Model { get; set; } + public string GetNullstringValue() + { + return this.GetNullstringValue(); + } } } diff --git a/MbSoftlab.TemplateEngine.Core.Demo/Program.cs b/MbSoftlab.TemplateEngine.Core.Demo/Program.cs index 99ba2b1..97ceb05 100644 --- a/MbSoftlab.TemplateEngine.Core.Demo/Program.cs +++ b/MbSoftlab.TemplateEngine.Core.Demo/Program.cs @@ -1,6 +1,8 @@ using MbSoftLab.TemplateEngine.Core; using System; using System.Collections.Generic; +using System.Diagnostics; +using System.IO; namespace MbSoftLab.TemplateEngine.Core.Demo { @@ -42,10 +44,16 @@ static void Main(string[] args) }; + ITemplateEngine templateEngine = new RazorTemplateEngine(); templateEngine.LoadTemplateFromFile("TestModel.cshtml"); - Console.WriteLine(templateEngine.CreateStringFromTemplate(testModel)); + string templateFileContent = templateEngine.CreateStringFromTemplate(testModel); + Console.WriteLine(); + Console.WriteLine(templateFileContent); + var htmlFileName = Path.Combine(Path.GetTempPath(), "temp.html"); + File.WriteAllText(htmlFileName, templateFileContent); + Process.Start(@"cmd.exe ", $@"/c {htmlFileName}"); Console.ReadLine(); diff --git a/MbSoftlab.TemplateEngine.Core.Demo/TestModel.cshtml b/MbSoftlab.TemplateEngine.Core.Demo/TestModel.cshtml index 199bf9a..1da6af3 100644 --- a/MbSoftlab.TemplateEngine.Core.Demo/TestModel.cshtml +++ b/MbSoftlab.TemplateEngine.Core.Demo/TestModel.cshtml @@ -1,5 +1,7 @@ @inherits MbSoftLab.TemplateEngine.Core.Demo.Person -Hello @Model.FirstName +@* @using MbSoftLab.TemplateEngine.Core.Demo ToDo: Add Support for using Namespce*@ + +Hello @Model.FirstName;

Your tags are

@foreach (string tag in Model.Tags) From 3c9666560914d9153494546fe4b230c06471ce1b Mon Sep 17 00:00:00 2001 From: mbsoftlab Date: Thu, 31 Dec 2020 23:11:28 +0100 Subject: [PATCH 08/28] Refactor --- MbSoftlab.TemplateEngine.Core.Demo/TestModel.cshtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MbSoftlab.TemplateEngine.Core.Demo/TestModel.cshtml b/MbSoftlab.TemplateEngine.Core.Demo/TestModel.cshtml index 1da6af3..e42795d 100644 --- a/MbSoftlab.TemplateEngine.Core.Demo/TestModel.cshtml +++ b/MbSoftlab.TemplateEngine.Core.Demo/TestModel.cshtml @@ -1,7 +1,7 @@ @inherits MbSoftLab.TemplateEngine.Core.Demo.Person @* @using MbSoftLab.TemplateEngine.Core.Demo ToDo: Add Support for using Namespce*@ -Hello @Model.FirstName; +

Hello @Model.FirstName

Your tags are

@foreach (string tag in Model.Tags) From 68032152eeb5f2bcfe43c8208dca3f1eeeaecec8 Mon Sep 17 00:00:00 2001 From: mbsoftlab Date: Thu, 31 Dec 2020 23:59:04 +0100 Subject: [PATCH 09/28] BugFix UnitTest RazorTemplateEngine --- .../RazorTemplateEngineUnitTest.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/MbSoftLab.TemplateEngine.Core.Tests/RazorTemplateEngineUnitTest.cs b/MbSoftLab.TemplateEngine.Core.Tests/RazorTemplateEngineUnitTest.cs index 9b4873f..4c3fb63 100644 --- a/MbSoftLab.TemplateEngine.Core.Tests/RazorTemplateEngineUnitTest.cs +++ b/MbSoftLab.TemplateEngine.Core.Tests/RazorTemplateEngineUnitTest.cs @@ -297,15 +297,15 @@ public void can_handle_date_values_from_propertys() //Assert Prüfen der Ergebnisse Assert.AreEqual(expectedReturnString, returnString); } - [TestCase] + //[TestCase] ToDo: Add Support for Change Culture info public void can_create_and_use_SpecificCulture() { //Arrange string propertyName = "DummyDoubleProp1"; double value = 1.75; - string expectedOutput = Convert.ToString(value, CultureInfo.CreateSpecificCulture("de-DE")); + string expectedOutput = Convert.ToString(value); var sut = new RazorTemplateEngine(GetTemplateDataModelDummy(), "@Model." + propertyName + ""); - sut.CultureInfo = CultureInfo.CreateSpecificCulture("de-DE"); + sut.CultureInfo = CultureInfo.CreateSpecificCulture("en-US"); string expectedReturnString = "" + expectedOutput + ""; //Act From ee6a45e8b327b51d6e50ac75f80176916c93c7f4 Mon Sep 17 00:00:00 2001 From: mbsoftlab Date: Fri, 1 Jan 2021 00:16:13 +0100 Subject: [PATCH 10/28] Add NuGet official package source in Workflows --- .github/workflows/BuildFromDevelop.yml | 4 +++- .github/workflows/BuildFromMaster.yml | 4 +++- .github/workflows/Release.yml | 4 +++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/.github/workflows/BuildFromDevelop.yml b/.github/workflows/BuildFromDevelop.yml index 1b33baa..0bf746b 100644 --- a/.github/workflows/BuildFromDevelop.yml +++ b/.github/workflows/BuildFromDevelop.yml @@ -18,7 +18,9 @@ jobs: with: dotnet-version: 3.1.301 - name: Install dependencies - run: dotnet restore + run: | + nuget sources add -name "NuGet official package source" -Source https://api.nuget.org/v3/index.json + dotnet restore - name: Build run: dotnet build --configuration Release --no-restore - name: Test diff --git a/.github/workflows/BuildFromMaster.yml b/.github/workflows/BuildFromMaster.yml index a9e3665..99ce2ed 100644 --- a/.github/workflows/BuildFromMaster.yml +++ b/.github/workflows/BuildFromMaster.yml @@ -18,7 +18,9 @@ jobs: with: dotnet-version: 3.1.301 - name: Install dependencies - run: dotnet restore + run: | + nuget sources add -name "NuGet official package source" -Source https://api.nuget.org/v3/index.json + dotnet restore - name: Build run: dotnet build --configuration Release --no-restore - name: Test diff --git a/.github/workflows/Release.yml b/.github/workflows/Release.yml index baebd7c..49559df 100644 --- a/.github/workflows/Release.yml +++ b/.github/workflows/Release.yml @@ -15,7 +15,9 @@ jobs: with: dotnet-version: 3.1.301 - name: Install dependencies - run: dotnet restore + run: | + nuget sources add -name "NuGet official package source" -Source https://api.nuget.org/v3/index.json + dotnet restore - name: Build run: dotnet build --configuration Release --no-restore - name: Publish to NuGet From ce5fa9c1a6245ccb9dd9ec3432306bb754ec41a6 Mon Sep 17 00:00:00 2001 From: mbsoftlab Date: Fri, 1 Jan 2021 00:22:38 +0100 Subject: [PATCH 11/28] Refactorings --- .../RazorTemplateEngineUnitTest.cs | 6 --- .../PlaceholderValueRaplacer.cs | 52 ++----------------- 2 files changed, 4 insertions(+), 54 deletions(-) diff --git a/MbSoftLab.TemplateEngine.Core.Tests/RazorTemplateEngineUnitTest.cs b/MbSoftLab.TemplateEngine.Core.Tests/RazorTemplateEngineUnitTest.cs index 4c3fb63..a812fcb 100644 --- a/MbSoftLab.TemplateEngine.Core.Tests/RazorTemplateEngineUnitTest.cs +++ b/MbSoftLab.TemplateEngine.Core.Tests/RazorTemplateEngineUnitTest.cs @@ -6,11 +6,9 @@ namespace TemplateEngineCore.Tests { - [TestFixture] public class RazorTemplateEngineUnitTest : UnitTestBase { - [Test] public void can_create_a_valid_string_from_template() { @@ -156,9 +154,6 @@ public void can_set_a_model_on_creating() //Assert Assert.AreEqual(expectedReturnString, returnString); } - - - [Test] public void throws_excepton_if_fileLoading_failed() { @@ -168,7 +163,6 @@ public void throws_excepton_if_fileLoading_failed() //Assert Assert.Throws(delegate { - //Act sut.LoadTemplateFromFile("NonExistingFile.txt"); }); diff --git a/MbSoftLab.TemplateEngine.Core/PlaceholderValueRaplacer.cs b/MbSoftLab.TemplateEngine.Core/PlaceholderValueRaplacer.cs index 7a18a46..6ebbec1 100644 --- a/MbSoftLab.TemplateEngine.Core/PlaceholderValueRaplacer.cs +++ b/MbSoftLab.TemplateEngine.Core/PlaceholderValueRaplacer.cs @@ -1,50 +1,8 @@ using System; -using System.Collections.Generic; using System.Globalization; -using System.Reflection; -using System.Text; namespace MbSoftLab.TemplateEngine.Core { - public class DisplaySetting : Attribute - { - private readonly string _value; - - - public string NullStringValue { get; set; } - public CultureInfo CultureInfo { get; set; } - } - public static class TemplateDataModelExtensions - { - public static string GetNullstringValue(this string value) - { - string output = null; - DisplaySetting[] attrs = GetDisplaySettingsFromTemplateDataModel(value); - - if (attrs.Length > 0) - output = attrs[0].NullStringValue; - - return output; - } - public static string ToString(this string value) - { - string output = null; - DisplaySetting[] attrs = GetDisplaySettingsFromTemplateDataModel(value); - - if (attrs.Length > 0) - output = attrs[0].NullStringValue; - - return output; - } - - private static DisplaySetting[] GetDisplaySettingsFromTemplateDataModel(string value) - { - Type type = value.GetType(); - FieldInfo fi = type.GetField(value.ToString()); - DisplaySetting[] attrs = fi.GetCustomAttributes(typeof(DisplaySetting), false) as DisplaySetting []; - return attrs; - } - } class PlaceholderValueRaplacer : IPlaceholderValueRaplacer { string _outputString; @@ -91,16 +49,14 @@ private void ReplaceNullableStringValueInOutputString(string placeholderValueNam if (value == null) _outputString = _outputString.Replace(placeholderValueName, _nullStringValue); else - _outputString = _outputString.Replace(placeholderValueName, (String)value); + _outputString = _outputString.Replace(placeholderValueName, (String)value); } public void ReplacePlaceholderWithValue(Type valueType, string placeholderValueName, object value) { if (IsNoCollection(valueType)) - _replacementActionCollection.InvokeReplacementActionForType(valueType, placeholderValueName, value); - } + _replacementActionCollection.InvokeReplacementActionForType(valueType, placeholderValueName, value); + } private bool IsNoCollection(Type valueType) => valueType.FullName.Contains("System.Collections.Generic") == false; - - } -} +} \ No newline at end of file From 046625d6f564e96b0bcb055cdf8009f348192aca Mon Sep 17 00:00:00 2001 From: mbsoftlab Date: Fri, 1 Jan 2021 00:25:06 +0100 Subject: [PATCH 12/28] Improvements --- MbSoftlab.TemplateEngine.Core.Demo/Address.cs | 8 +++++++ MbSoftlab.TemplateEngine.Core.Demo/Order.cs | 10 +++++++++ MbSoftlab.TemplateEngine.Core.Demo/Person.cs | 22 ++----------------- MbSoftlab.TemplateEngine.Core.Demo/Product.cs | 8 +++++++ 4 files changed, 28 insertions(+), 20 deletions(-) create mode 100644 MbSoftlab.TemplateEngine.Core.Demo/Address.cs create mode 100644 MbSoftlab.TemplateEngine.Core.Demo/Order.cs create mode 100644 MbSoftlab.TemplateEngine.Core.Demo/Product.cs diff --git a/MbSoftlab.TemplateEngine.Core.Demo/Address.cs b/MbSoftlab.TemplateEngine.Core.Demo/Address.cs new file mode 100644 index 0000000..eb1e359 --- /dev/null +++ b/MbSoftlab.TemplateEngine.Core.Demo/Address.cs @@ -0,0 +1,8 @@ +namespace MbSoftLab.TemplateEngine.Core.Demo +{ + public class Address + { + public string Street { get; set; } + public string PostCode { get; set; } + } +} diff --git a/MbSoftlab.TemplateEngine.Core.Demo/Order.cs b/MbSoftlab.TemplateEngine.Core.Demo/Order.cs new file mode 100644 index 0000000..7076ccf --- /dev/null +++ b/MbSoftlab.TemplateEngine.Core.Demo/Order.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; + +namespace MbSoftLab.TemplateEngine.Core.Demo +{ + public class Order + { + public int Id { get; set; } + public List Products { get; set; } + } +} diff --git a/MbSoftlab.TemplateEngine.Core.Demo/Person.cs b/MbSoftlab.TemplateEngine.Core.Demo/Person.cs index bc204bb..b34ca52 100644 --- a/MbSoftlab.TemplateEngine.Core.Demo/Person.cs +++ b/MbSoftlab.TemplateEngine.Core.Demo/Person.cs @@ -1,31 +1,13 @@ -using RazorEngineCore; -using System.Collections.Generic; +using System.Collections.Generic; namespace MbSoftLab.TemplateEngine.Core.Demo { - public class Person: TemplateDataModel + public class Person : TemplateDataModel { public string FirstName { get; set; } public string LastName { get; set; } public List Tags { get; set; } public Address Address { get; set; } public List Orders { get; set; } - - } - public class Address - { - public string Street { get; set; } - public string PostCode { get; set; } - } - public class Order - { - public int Id { get; set; } - public List Products { get; set; } - } - public class Product - { - public string ProductName { get; set; } - public float Price { get; set; } - } } diff --git a/MbSoftlab.TemplateEngine.Core.Demo/Product.cs b/MbSoftlab.TemplateEngine.Core.Demo/Product.cs new file mode 100644 index 0000000..5a3c2a3 --- /dev/null +++ b/MbSoftlab.TemplateEngine.Core.Demo/Product.cs @@ -0,0 +1,8 @@ +namespace MbSoftLab.TemplateEngine.Core.Demo +{ + public class Product + { + public string ProductName { get; set; } + public float Price { get; set; } + } +} From 825ae7790a0ed629b297ee0a3c41c884c02830ce Mon Sep 17 00:00:00 2001 From: mbsoftlab Date: Fri, 1 Jan 2021 00:25:58 +0100 Subject: [PATCH 13/28] improvements --- .../RazorTemplateEngineUnitTest.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/MbSoftLab.TemplateEngine.Core.Tests/RazorTemplateEngineUnitTest.cs b/MbSoftLab.TemplateEngine.Core.Tests/RazorTemplateEngineUnitTest.cs index a812fcb..506e695 100644 --- a/MbSoftLab.TemplateEngine.Core.Tests/RazorTemplateEngineUnitTest.cs +++ b/MbSoftLab.TemplateEngine.Core.Tests/RazorTemplateEngineUnitTest.cs @@ -174,7 +174,6 @@ public void can_handle_a_DataModel_with_a_list_property() var sut = new RazorTemplateEngine(GetTemplateDataModelDummyWithListAndMethod(), "@Model.DummyStringListProp2"); //SUT = [S]ystem [U]nder [T]est //Act / Assert Assert.DoesNotThrow(delegate { sut.CreateStringFromTemplate(); }); - } [Test] public void can_handle_a_Method_in_DataModel_without_Exeption() From ec94da2a90dc7bb8f5a6b7222ad2f2c50a04f1b9 Mon Sep 17 00:00:00 2001 From: mbsoftlab Date: Fri, 1 Jan 2021 00:26:48 +0100 Subject: [PATCH 14/28] improvements --- MbSoftLab.TemplateEngine.Core/TemplateDataModelProcessor.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/MbSoftLab.TemplateEngine.Core/TemplateDataModelProcessor.cs b/MbSoftLab.TemplateEngine.Core/TemplateDataModelProcessor.cs index c2360f6..d32c676 100644 --- a/MbSoftLab.TemplateEngine.Core/TemplateDataModelProcessor.cs +++ b/MbSoftLab.TemplateEngine.Core/TemplateDataModelProcessor.cs @@ -18,7 +18,6 @@ private void AddMethodsFromTemplateDataModelBaseClassToBlacklist() new TemplateDataModel().GetType() .GetMethods().ToList() .ForEach(method=>_methodBlacklist.Add(method.Name)); - } public TemplateDataModelProcessor(string openingDelimiter, string closeingDelimiter, IPlaceholderValueRaplacer placeholderValueRaplacer) { From 974ffcece5917d2d2dd3e3056314abd444f0b649 Mon Sep 17 00:00:00 2001 From: mbsoftlab Date: Fri, 1 Jan 2021 00:29:47 +0100 Subject: [PATCH 15/28] Reformat --- MbSoftLab.TemplateEngine.Core/ITemplateEngine.cs | 1 - MbSoftLab.TemplateEngine.Core/RazorTemplateEngine.cs | 1 - MbSoftLab.TemplateEngine.Core/ReplacementActionCollection.cs | 3 +-- MbSoftLab.TemplateEngine.Core/TemplateDataModel.cs | 3 +-- MbSoftLab.TemplateEngine.Core/TemplateDataModelProcessor.cs | 5 ++--- MbSoftLab.TemplateEngine.Core/TemplateEngineConfig.cs | 5 +---- 6 files changed, 5 insertions(+), 13 deletions(-) diff --git a/MbSoftLab.TemplateEngine.Core/ITemplateEngine.cs b/MbSoftLab.TemplateEngine.Core/ITemplateEngine.cs index efe3271..26f81fa 100644 --- a/MbSoftLab.TemplateEngine.Core/ITemplateEngine.cs +++ b/MbSoftLab.TemplateEngine.Core/ITemplateEngine.cs @@ -11,7 +11,6 @@ public interface ITemplateEngine string OpeningDelimiter { get; set; } T TemplateDataModel { get; set; } string TemplateString { get; set; } - string CreateStringFromTemplate(string stringTemplate = null); string CreateStringFromTemplate(T templateDataModel); string CreateStringFromTemplate(T templateDataModel, string stringTemplate); diff --git a/MbSoftLab.TemplateEngine.Core/RazorTemplateEngine.cs b/MbSoftLab.TemplateEngine.Core/RazorTemplateEngine.cs index 0e5ae59..672dbb6 100644 --- a/MbSoftLab.TemplateEngine.Core/RazorTemplateEngine.cs +++ b/MbSoftLab.TemplateEngine.Core/RazorTemplateEngine.cs @@ -68,7 +68,6 @@ public string CreateStringFromTemplate(string csHtmlTemplate = null) string result = template.Run(TemplateDataModel); return result; } - public string CreateStringFromTemplate(T templateDataModel) { TemplateDataModel = templateDataModel; diff --git a/MbSoftLab.TemplateEngine.Core/ReplacementActionCollection.cs b/MbSoftLab.TemplateEngine.Core/ReplacementActionCollection.cs index a02b642..ad6fe00 100644 --- a/MbSoftLab.TemplateEngine.Core/ReplacementActionCollection.cs +++ b/MbSoftLab.TemplateEngine.Core/ReplacementActionCollection.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Text; namespace MbSoftLab.TemplateEngine.Core { @@ -23,4 +22,4 @@ public void InvokeReplacementActionForType(Type valueType, string placeholderVal throw new NotSupportedException($"Type '{valueType}' not supported by TemplateEngine.createStringFromTemplate()."); } } -} +} \ No newline at end of file diff --git a/MbSoftLab.TemplateEngine.Core/TemplateDataModel.cs b/MbSoftLab.TemplateEngine.Core/TemplateDataModel.cs index 6c3a5b5..efe1ebe 100644 --- a/MbSoftLab.TemplateEngine.Core/TemplateDataModel.cs +++ b/MbSoftLab.TemplateEngine.Core/TemplateDataModel.cs @@ -3,7 +3,6 @@ namespace MbSoftLab.TemplateEngine.Core { - public class TemplateDataModel : RazorEngineTemplateBase { [JsonIgnore] @@ -13,4 +12,4 @@ public string GetNullstringValue() return this.GetNullstringValue(); } } -} +} \ No newline at end of file diff --git a/MbSoftLab.TemplateEngine.Core/TemplateDataModelProcessor.cs b/MbSoftLab.TemplateEngine.Core/TemplateDataModelProcessor.cs index d32c676..80829dc 100644 --- a/MbSoftLab.TemplateEngine.Core/TemplateDataModelProcessor.cs +++ b/MbSoftLab.TemplateEngine.Core/TemplateDataModelProcessor.cs @@ -2,11 +2,10 @@ using System.Collections.Generic; using System.Linq; using System.Reflection; -using System.Text; namespace MbSoftLab.TemplateEngine.Core { - class TemplateDataModelProcessor + class TemplateDataModelProcessor { string _openingDelimiter, _closeingDelimiter; private List _methodBlacklist = new List() { "ToString", "GetType", "Equals", "GetHashCode" }; @@ -88,4 +87,4 @@ private void ProcessTemplateDataModelClassPropertys(object templateDataModel) } } } -} +} \ No newline at end of file diff --git a/MbSoftLab.TemplateEngine.Core/TemplateEngineConfig.cs b/MbSoftLab.TemplateEngine.Core/TemplateEngineConfig.cs index 7ff0d5c..ff8687e 100644 --- a/MbSoftLab.TemplateEngine.Core/TemplateEngineConfig.cs +++ b/MbSoftLab.TemplateEngine.Core/TemplateEngineConfig.cs @@ -1,10 +1,7 @@ -using System.Collections.Generic; -using System.Globalization; -using System.Text; +using System.Globalization; namespace MbSoftLab.TemplateEngine.Core { - /// /// /// From 37c73df18bc1f38866cfef9ce4430a4cfa277002 Mon Sep 17 00:00:00 2001 From: mbsoftlab Date: Fri, 1 Jan 2021 00:31:13 +0100 Subject: [PATCH 16/28] Reformat --- .../RazorTemplateEngine.cs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/MbSoftLab.TemplateEngine.Core/RazorTemplateEngine.cs b/MbSoftLab.TemplateEngine.Core/RazorTemplateEngine.cs index 672dbb6..4b65cfa 100644 --- a/MbSoftLab.TemplateEngine.Core/RazorTemplateEngine.cs +++ b/MbSoftLab.TemplateEngine.Core/RazorTemplateEngine.cs @@ -7,7 +7,7 @@ namespace MbSoftLab.TemplateEngine.Core { - public class RazorTemplateEngine : ITemplateEngine where T: TemplateDataModel + public class RazorTemplateEngine : ITemplateEngine where T : TemplateDataModel { public string CloseingDelimiter { get { Console.WriteLine($"RazorTemplateEngine has no {nameof(CloseingDelimiter)}"); return ""; } set => Console.WriteLine($"Can not set {nameof(CloseingDelimiter)} for RazorTemplateEngine"); } ITemplateEngineConfig _config; @@ -25,11 +25,12 @@ public ITemplateEngineConfig Config this.CultureInfo = _config.CultureInfo; } } - public CultureInfo CultureInfo { get { Console.WriteLine($"{nameof(RazorTemplateEngine)} can not maipulate {nameof(CultureInfo)}"); return null;} set => Console.WriteLine($"{nameof(RazorTemplateEngine)} can not maipulate {nameof(CultureInfo)}"); } - - public string NullStringValue { + public CultureInfo CultureInfo { get { Console.WriteLine($"{nameof(RazorTemplateEngine)} can not maipulate {nameof(CultureInfo)}"); return null; } set => Console.WriteLine($"{nameof(RazorTemplateEngine)} can not maipulate {nameof(CultureInfo)}"); } + + public string NullStringValue + { get => "String.Empty"; - set {Console.WriteLine(new WarningException($"{nameof(RazorTemplateEngine)} can not maipulate {nameof(NullStringValue)}").Message);} + set { Console.WriteLine(new WarningException($"{nameof(RazorTemplateEngine)} can not maipulate {nameof(NullStringValue)}").Message); } } public string OpeningDelimiter { @@ -44,7 +45,7 @@ public string OpeningDelimiter } } public T TemplateDataModel { get; set; } - public string TemplateString { get ; set ; } + public string TemplateString { get; set; } IRazorEngine razorEngine; public RazorTemplateEngine(IRazorEngine razorEngine) { @@ -54,7 +55,7 @@ public RazorTemplateEngine() { razorEngine = new RazorEngine(); } - public RazorTemplateEngine(T dataModel, string templateString ) + public RazorTemplateEngine(T dataModel, string templateString) { razorEngine = new RazorEngine(); TemplateDataModel = dataModel; @@ -72,7 +73,7 @@ public string CreateStringFromTemplate(T templateDataModel) { TemplateDataModel = templateDataModel; return CreateStringFromTemplate(); - + } public string CreateStringFromTemplate(T templateDataModel, string csHtmlTemplate) From 3919257b7fbf06e43f48e41dc4ad68218c5f7403 Mon Sep 17 00:00:00 2001 From: mbsoftlab Date: Fri, 1 Jan 2021 00:33:53 +0100 Subject: [PATCH 17/28] reformat --- MbSoftLab.TemplateEngine.Core/RazorTemplateEngine.cs | 1 - MbSoftLab.TemplateEngine.Core/TemplateDataModelProcessor.cs | 1 - MbSoftLab.TemplateEngine.Core/TemplateEngine.cs | 4 ---- MbSoftLab.TemplateEngine.Core/TemplateEngineConfig.cs | 2 +- 4 files changed, 1 insertion(+), 7 deletions(-) diff --git a/MbSoftLab.TemplateEngine.Core/RazorTemplateEngine.cs b/MbSoftLab.TemplateEngine.Core/RazorTemplateEngine.cs index 4b65cfa..990f985 100644 --- a/MbSoftLab.TemplateEngine.Core/RazorTemplateEngine.cs +++ b/MbSoftLab.TemplateEngine.Core/RazorTemplateEngine.cs @@ -73,7 +73,6 @@ public string CreateStringFromTemplate(T templateDataModel) { TemplateDataModel = templateDataModel; return CreateStringFromTemplate(); - } public string CreateStringFromTemplate(T templateDataModel, string csHtmlTemplate) diff --git a/MbSoftLab.TemplateEngine.Core/TemplateDataModelProcessor.cs b/MbSoftLab.TemplateEngine.Core/TemplateDataModelProcessor.cs index 80829dc..f37ebc5 100644 --- a/MbSoftLab.TemplateEngine.Core/TemplateDataModelProcessor.cs +++ b/MbSoftLab.TemplateEngine.Core/TemplateDataModelProcessor.cs @@ -77,7 +77,6 @@ private void ProcessTemplateDataModelClassPropertys(object templateDataModel) try { _placeholderValueRaplacer.ReplacePlaceholderWithValue(propertyValueType, propertyName, propertyValue); - } catch (Exception ex) { diff --git a/MbSoftLab.TemplateEngine.Core/TemplateEngine.cs b/MbSoftLab.TemplateEngine.Core/TemplateEngine.cs index 52ed870..5b556c0 100644 --- a/MbSoftLab.TemplateEngine.Core/TemplateEngine.cs +++ b/MbSoftLab.TemplateEngine.Core/TemplateEngine.cs @@ -85,7 +85,6 @@ public ITemplateEngineConfig Config private ITemplateEngineConfig _config; #endregion - #region --- CONSTRUCTORS public TemplateEngine(T templateDataModel, string stringTemplate) { @@ -120,7 +119,6 @@ public string CreateStringFromTemplate(string stringTemplate = null) { throw ex; } - } /// /// Replaces all Propertys of templateDataModel in stringTemplate. The Popertynames from templateDataModel a the name of ${Placeholder} have to be equal. @@ -160,7 +158,5 @@ private string CreateStringFromTemplate() return placeholderValueRaplacer.OutputString; } - } - } \ No newline at end of file diff --git a/MbSoftLab.TemplateEngine.Core/TemplateEngineConfig.cs b/MbSoftLab.TemplateEngine.Core/TemplateEngineConfig.cs index ff8687e..445d0c2 100644 --- a/MbSoftLab.TemplateEngine.Core/TemplateEngineConfig.cs +++ b/MbSoftLab.TemplateEngine.Core/TemplateEngineConfig.cs @@ -23,4 +23,4 @@ public class TemplateEngineConfig : ITemplateEngineConfig public string NullStringValue { get => _nullStringValue; set => _nullStringValue=value; } private string _nullStringValue; } -} +} \ No newline at end of file From 33e59947b30a9e8ebaa87c275ae6e17d2d0605dd Mon Sep 17 00:00:00 2001 From: mbsoftlab Date: Fri, 1 Jan 2021 01:29:52 +0100 Subject: [PATCH 18/28] Fixed Typo --- .../TemplateDataModelDummy.cs | 20 ++----------------- 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/MbSoftLab.TemplateEngine.Core.Tests/TemplateDataModelDummy.cs b/MbSoftLab.TemplateEngine.Core.Tests/TemplateDataModelDummy.cs index d262dde..cf2f404 100644 --- a/MbSoftLab.TemplateEngine.Core.Tests/TemplateDataModelDummy.cs +++ b/MbSoftLab.TemplateEngine.Core.Tests/TemplateDataModelDummy.cs @@ -1,45 +1,29 @@ using MbSoftLab.TemplateEngine.Core; using System; -using System.ComponentModel.DataAnnotations; namespace TemplateEngineCore.Tests { - public class TemplateDataModelDummy:TemplateDataModel + public class TemplateDataModelDummy : TemplateDataModel { - - public string DummyStringProp1 { get; set; } - - - [DisplaySetting(NullStringValue ="Nothing")] public string DummyStringProp2 { get; set; } - public DateTime DummyDateTimeProp1 { get; set; } - public int DummyIntProp1 { get; set; } public int DummyIntProp2 { get; set; } - public Int64 DummyInt64Prop { get; set; } - public UInt16 DummyUInt16 { get; set; } - public Int16 DummyInt16 { get; set; } public Decimal DummyDecimalProp { get; set; } - public byte DummyByteProp { get; set; } public sbyte DummySByteProp { get; set; } public char DummyCharProp { get; set; } - public double DummyDoubleProp1 { get; set; } public double DummyDoubleProp2 { get; set; } - public bool DummBoolProp1 { get; set; } public bool DummyBoolProp2 { get; set; } - public bool? DummyBoolQProp1 { get; set; } public bool? DummyBoolQProp2 { get; set; } - public object DummyObjectProp1 { get; set; } public object DummyObjectProp2 { get; set; } } -} +} \ No newline at end of file From 3f7da73783ef69612f0136761f047319a399e8d9 Mon Sep 17 00:00:00 2001 From: mbsoftlab Date: Sat, 2 Jan 2021 15:12:28 +0100 Subject: [PATCH 19/28] Updated Description and Tags --- .../MbSoftLab.TemplateEngine.Core.csproj | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/MbSoftLab.TemplateEngine.Core/MbSoftLab.TemplateEngine.Core.csproj b/MbSoftLab.TemplateEngine.Core/MbSoftLab.TemplateEngine.Core.csproj index fd6eaf1..53c804a 100644 --- a/MbSoftLab.TemplateEngine.Core/MbSoftLab.TemplateEngine.Core.csproj +++ b/MbSoftLab.TemplateEngine.Core/MbSoftLab.TemplateEngine.Core.csproj @@ -2,20 +2,20 @@ netcoreapp3.1 - 1.0.8.1 - 1.0.8.1 + 1.0.8.2 + 1.0.8.2 1.0.8 1.0.8-preview2 - This StringTemplateEngine can replace values from Classpropertys and methods in stringtemplates + This TemplateEngine can replace values from Classpropertys and methods in simple stringtemplates with a very good performance. The Engine supports the RazorLanguage for creating complex html templates. Documentation.xml true true - Template Engine TemplateEngine StringTemplates C#-Template-Engine + Template Engine TemplateEngine StringTemplates C#-Template-Engine Razor Razortemplates Razorengine html MbSoftLab.TemplateEngine.Core MbSoftLab MbSoftLab MIT - © 2020 MbSoftLab + © 2021 MbSoftLab MbSoftLabLogo.png https://github.com/mbsoftlab/MbSoftLab.TemplateEngine.Core From f5c00d975536d135422fa4d84fee9f1502aaa678 Mon Sep 17 00:00:00 2001 From: mbsoftlab Date: Sat, 2 Jan 2021 15:25:44 +0100 Subject: [PATCH 20/28] Renamings in TemplateEngineUnitTests --- .../TemplateEngineUnitTest.cs | 120 +++++++++--------- 1 file changed, 60 insertions(+), 60 deletions(-) diff --git a/MbSoftLab.TemplateEngine.Core.Tests/TemplateEngineUnitTest.cs b/MbSoftLab.TemplateEngine.Core.Tests/TemplateEngineUnitTest.cs index 5dd3ef1..7467106 100644 --- a/MbSoftLab.TemplateEngine.Core.Tests/TemplateEngineUnitTest.cs +++ b/MbSoftLab.TemplateEngine.Core.Tests/TemplateEngineUnitTest.cs @@ -16,13 +16,13 @@ public void can_create_a_valid_string_from_template() { //Arrange var sut = new TemplateEngine(GetTemplateDataModelDummy(), "${DummyStringProp1}"); //SUT = [S]ystem [U]nder [T]est - string ShouldReturnString = "DummyStringProp1Value"; + string expectedReturnString = "DummyStringProp1Value"; - //Act Ausführen der zu testenden Funktion - string ReturnString = sut.CreateStringFromTemplate(); + //Act + string returnString = sut.CreateStringFromTemplate(); //Assert - Assert.AreEqual(ShouldReturnString, ReturnString); + Assert.AreEqual(expectedReturnString, returnString); } [Test] public void can_create_a_valid_string_from_template_with_json() @@ -30,27 +30,27 @@ public void can_create_a_valid_string_from_template_with_json() //Arrange var sut = new TemplateEngine(); //SUT = [S]ystem [U]nder [T]est sut.TemplateString = "${DummyStringProp1}"; - string ShouldReturnString = "DummyStringProp1Value"; + string expectedReturnString = "DummyStringProp1Value"; string jsonData = GetDummyJson(); - //Act Ausführen der zu testenden Funktion - string ReturnString = sut.CreateStringFromTemplateWithJson(jsonData); + //Act + string returnString = sut.CreateStringFromTemplateWithJson(jsonData); //Assert - Assert.AreEqual(ShouldReturnString, ReturnString); + Assert.AreEqual(expectedReturnString, returnString); } [Test] public void can_handle_null_Values_in_Propertys() { //Arrange var sut = new TemplateEngine(GetTemplateDataModelDummy(), "${DummyStringProp2}"); //SUT = [S]ystem [U]nder [T]est - string ShouldReturnString = "NULL"; + string expectedReturnString = "NULL"; - //Act Ausführen der zu testenden Funktion - string ReturnString = sut.CreateStringFromTemplate(); + //Act + string returnString = sut.CreateStringFromTemplate(); //Assert - Assert.AreEqual(ShouldReturnString, ReturnString); + Assert.AreEqual(expectedReturnString, returnString); } [Test] public void can_set_a_custom_null_value_String() @@ -58,13 +58,13 @@ public void can_set_a_custom_null_value_String() //Arrange var sut = new TemplateEngine(GetTemplateDataModelDummy(), "${DummyStringProp2}"); //SUT = [S]ystem [U]nder [T]est sut.NullStringValue = "Nothing"; - string ShouldReturnString = "Nothing"; + string expectedReturnString = "Nothing"; //Act - string ReturnString = sut.CreateStringFromTemplate(); + string returnString = sut.CreateStringFromTemplate(); //Assert - Assert.AreEqual(ShouldReturnString, ReturnString); + Assert.AreEqual(expectedReturnString, returnString); } [Test] public void can_set_a_template() @@ -73,13 +73,13 @@ public void can_set_a_template() var sut = new TemplateEngine(GetTemplateDataModelDummy(), "${DummyStringProp2}"); //SUT = [S]ystem [U]nder [T]est sut.NullStringValue = "Nothing"; sut.TemplateString = "${DummyStringProp2}"; - string ShouldReturnString = "Nothing"; + string expectedReturnString = "Nothing"; //Act - string ReturnString = sut.CreateStringFromTemplate(); + string returnString = sut.CreateStringFromTemplate(); //Assert - Assert.AreEqual(ShouldReturnString, ReturnString); + Assert.AreEqual(expectedReturnString, returnString); } [Test] public void can_use_the_config() @@ -97,13 +97,13 @@ public void can_use_the_config() var sut = new TemplateEngine(); //SUT = [S]ystem [U]nder [T]est sut.Config = templateEngineConfig; - string ShouldReturnString = "---"; + string expectedReturnString = "---"; //Act - string ReturnString = sut.CreateStringFromTemplate(); + string returnString = sut.CreateStringFromTemplate(); //Assert - Assert.AreEqual(ShouldReturnString, ReturnString); + Assert.AreEqual(expectedReturnString, returnString); } [Test] public void can_use_the_generic_config() @@ -121,13 +121,13 @@ public void can_use_the_generic_config() var sut = new TemplateEngine(); sut.Config = templateEngineConfig; - string ShouldReturnString = "---"; + string expectedReturnString = "---"; //Act - string ReturnString = sut.CreateStringFromTemplate(); + string returnString = sut.CreateStringFromTemplate(); //Assert - Assert.AreEqual(ShouldReturnString, ReturnString); + Assert.AreEqual(expectedReturnString, returnString); } [Test] public void can_set_a_template_and_model_on_creating() @@ -135,13 +135,13 @@ public void can_set_a_template_and_model_on_creating() //Arrange var sut = new TemplateEngine(); sut.NullStringValue = "Nothing"; - string ShouldReturnString = "Nothing"; + string expectedReturnString = "Nothing"; //Act - string ReturnString = sut.CreateStringFromTemplate(GetTemplateDataModelDummy(), "${DummyStringProp2}"); + string returnString = sut.CreateStringFromTemplate(GetTemplateDataModelDummy(), "${DummyStringProp2}"); //Assert - Assert.AreEqual(ShouldReturnString, ReturnString); + Assert.AreEqual(expectedReturnString, returnString); } [Test] public void can_set_a_model_on_creating() @@ -150,13 +150,13 @@ public void can_set_a_model_on_creating() var sut = new TemplateEngine(); sut.NullStringValue = "Nothing"; sut.TemplateString = "${DummyStringProp2}"; - string ShouldReturnString = "Nothing"; + string expectedReturnString = "Nothing"; //Act - string ReturnString = sut.CreateStringFromTemplate(GetTemplateDataModelDummy()); + string returnString = sut.CreateStringFromTemplate(GetTemplateDataModelDummy()); //Assert - Assert.AreEqual(ShouldReturnString, ReturnString); + Assert.AreEqual(expectedReturnString, returnString); } [Test] public void can_set_a_DataModel_with_Annonymos_Type() @@ -165,13 +165,13 @@ public void can_set_a_DataModel_with_Annonymos_Type() var sut = new TemplateEngine(new { DummyStringProp2 = "2" }); //SUT = [S]ystem [U]nder [T]est sut.NullStringValue = "Nothing"; sut.TemplateString = "${DummyStringProp2}"; - string ShouldReturnString = "2"; + string expectedReturnString = "2"; //Act - string ReturnString = sut.CreateStringFromTemplate(); + string returnString = sut.CreateStringFromTemplate(); //Assert - Assert.AreEqual(ShouldReturnString, ReturnString); + Assert.AreEqual(expectedReturnString, returnString); } [Test] public void can_set_a_different_DataModel_with_annonymos_type_after_create_an_instance() @@ -181,13 +181,13 @@ public void can_set_a_different_DataModel_with_annonymos_type_after_create_an_in sut.NullStringValue = "Nothing"; sut.TemplateString = "${DummyStringProp2}"; sut.TemplateDataModel = new { DummyStringProp2 = "5" }; - string ShouldReturnString = "5"; + string expectedReturnString = "5"; //Act - string ReturnString = sut.CreateStringFromTemplate(); + string returnString = sut.CreateStringFromTemplate(); //Assert - Assert.AreEqual(ShouldReturnString, ReturnString); + Assert.AreEqual(expectedReturnString, returnString); } [Test] public void can_change_the_default_delimiters() @@ -199,13 +199,13 @@ public void can_change_the_default_delimiters() sut.NullStringValue = "Nothing"; sut.TemplateString = "{{DummyStringProp2}}"; sut.TemplateDataModel = new { DummyStringProp2 = "5" }; - string ShouldReturnString = "5"; + string expectedReturnString = "5"; //Act - string ReturnString = sut.CreateStringFromTemplate(); + string returnString = sut.CreateStringFromTemplate(); //Assert - Assert.AreEqual(ShouldReturnString, ReturnString); + Assert.AreEqual(expectedReturnString, returnString); } [Test] public void throws_exeption_if_type_not_supported() @@ -258,13 +258,13 @@ public void can_handle_return_values_from_a_method(string methodName, string ret //Arrange var sut = new TemplateEngine(GetTemplateDataModelDummyWithMethods(), "${" + methodName + "}"); //SUT = [S]ystem [U]nder [T]est - string ShouldReturnString = "" + returnValue + ""; + string expectedReturnString = "" + returnValue + ""; //Act - string ReturnString = sut.CreateStringFromTemplate(); + string returnString = sut.CreateStringFromTemplate(); //Assert - Assert.AreEqual(ShouldReturnString, ReturnString); + Assert.AreEqual(expectedReturnString, returnString); } [TestCase] public void can_handle_return_values_from_IntReturningMethod() @@ -274,13 +274,13 @@ public void can_handle_return_values_from_IntReturningMethod() string returnValue = Convert.ToString(Convert.ToInt32("12")); var sut = new TemplateEngine(GetTemplateDataModelDummyWithMethods(), "${" + methodName + "}"); //SUT = [S]ystem [U]nder [T]est - string ShouldReturnString = "" + returnValue + ""; + string expectedReturnString = "" + returnValue + ""; //Act - string ReturnString = sut.CreateStringFromTemplate(); + string returnString = sut.CreateStringFromTemplate(); //Assert - Assert.AreEqual(ShouldReturnString, ReturnString); + Assert.AreEqual(expectedReturnString, returnString); } [TestCase] public void can_handle_return_values_from_DoubleReturningMethod() @@ -291,13 +291,13 @@ public void can_handle_return_values_from_DoubleReturningMethod() string returnValue = Convert.ToString(value, CultureInfo.CreateSpecificCulture("en-US")); var sut = new TemplateEngine(GetTemplateDataModelDummyWithMethods(), "${" + methodName + "}"); //SUT = [S]ystem [U]nder [T]est - string ShouldReturnString = "" + returnValue + ""; + string expectedReturnString = "" + returnValue + ""; //Act - string ReturnString = sut.CreateStringFromTemplate(); + string returnString = sut.CreateStringFromTemplate(); //Assert - Assert.AreEqual(ShouldReturnString, ReturnString); + Assert.AreEqual(expectedReturnString, returnString); } [Test] [TestCase("DummyByteProp", "255")] @@ -317,13 +317,13 @@ public void can_handle_values_from_propertys(string propertyName, string expecte { //Arrange var sut = new TemplateEngine(GetTemplateDataModelDummy(), "${" + propertyName + "}"); //SUT = [S]ystem [U]nder [T]est - string ShouldReturnString = "" + expectedOutput + ""; + string expectedReturnString = "" + expectedOutput + ""; //Act - string ReturnString = sut.CreateStringFromTemplate(); + string returnString = sut.CreateStringFromTemplate(); //Assert - Assert.AreEqual(ShouldReturnString, ReturnString); + Assert.AreEqual(expectedReturnString, returnString); } [TestCase] public void can_handle_double_values_from_propertys() @@ -333,13 +333,13 @@ public void can_handle_double_values_from_propertys() double value = 1.75; string expectedOutput = Convert.ToString(value, CultureInfo.CreateSpecificCulture("en-US")); var sut = new TemplateEngine(GetTemplateDataModelDummy(), "${" + propertyName + "}"); //SUT = [S]ystem [U]nder [T]est - string ShouldReturnString = "" + expectedOutput + ""; + string expectedReturnString = "" + expectedOutput + ""; //Act - string ReturnString = sut.CreateStringFromTemplate(); + string returnString = sut.CreateStringFromTemplate(); //Assert - Assert.AreEqual(ShouldReturnString, ReturnString); + Assert.AreEqual(expectedReturnString, returnString); } [TestCase] public void can_handle_date_values_from_propertys() @@ -350,13 +350,13 @@ public void can_handle_date_values_from_propertys() //Arrange -> Vorbereiten der Testumgebung und der benötigten Prameter var sut = new TemplateEngine(GetTemplateDataModelDummy(), "${" + propertyName + "}"); //SUT = [S]ystem [U]nder [T]est - string ShouldReturnString = "" + expectedOutput + ""; + string expectedReturnString = "" + expectedOutput + ""; //Act Ausführen der zu testenden Funktion - string ReturnString = sut.CreateStringFromTemplate(); + string returnString = sut.CreateStringFromTemplate(); //Assert Prüfen der Ergebnisse - Assert.AreEqual(ShouldReturnString, ReturnString); + Assert.AreEqual(expectedReturnString, returnString); } [TestCase] public void can_create_and_use_SpecificCulture() @@ -367,13 +367,13 @@ public void can_create_and_use_SpecificCulture() string expectedOutput = Convert.ToString(value, CultureInfo.CreateSpecificCulture("de-DE")); TemplateEngine sut = new TemplateEngine(GetTemplateDataModelDummy(), "${" + propertyName + "}"); sut.CultureInfo = CultureInfo.CreateSpecificCulture("de-DE"); - string ShouldReturnString = "" + expectedOutput + ""; + string expectedReturnString = "" + expectedOutput + ""; //Act - string ReturnString = sut.CreateStringFromTemplate(); + string returnString = sut.CreateStringFromTemplate(); //Assert - Assert.AreEqual(ShouldReturnString, ReturnString); + Assert.AreEqual(expectedReturnString, returnString); } } } \ No newline at end of file From 7e72a504497c4f0d03674258675f7e8ba8761854 Mon Sep 17 00:00:00 2001 From: mbsoftlab Date: Sat, 2 Jan 2021 15:26:22 +0100 Subject: [PATCH 21/28] Removed Comment --- .../TemplateEngineUnitTest.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/MbSoftLab.TemplateEngine.Core.Tests/TemplateEngineUnitTest.cs b/MbSoftLab.TemplateEngine.Core.Tests/TemplateEngineUnitTest.cs index 7467106..e58bb03 100644 --- a/MbSoftLab.TemplateEngine.Core.Tests/TemplateEngineUnitTest.cs +++ b/MbSoftLab.TemplateEngine.Core.Tests/TemplateEngineUnitTest.cs @@ -347,15 +347,15 @@ public void can_handle_date_values_from_propertys() string propertyName = "DummyDateTimeProp1"; string expectedOutput = Convert.ToString(Convert.ToDateTime("01.01.2020 00:00:00"), CultureInfo.CreateSpecificCulture("en-US")); - //Arrange -> Vorbereiten der Testumgebung und der benötigten Prameter + //Arrange var sut = new TemplateEngine(GetTemplateDataModelDummy(), "${" + propertyName + "}"); //SUT = [S]ystem [U]nder [T]est string expectedReturnString = "" + expectedOutput + ""; - //Act Ausführen der zu testenden Funktion + //Act string returnString = sut.CreateStringFromTemplate(); - //Assert Prüfen der Ergebnisse + //Assert Assert.AreEqual(expectedReturnString, returnString); } [TestCase] From ed943b323b7083b36630032436ca1eda94948767 Mon Sep 17 00:00:00 2001 From: Justin <50733221+jupre003@users.noreply.github.com> Date: Fri, 5 Dec 2025 22:37:16 +0000 Subject: [PATCH 22/28] Aktualisiere Ziel-Framework auf net8.0 und aktualisiere Paketversionen; modernisierte Programmlogik auf TopLevelStatements --- ...MbSoftLab.TemplateEngine.Core.Tests.csproj | 8 +- .../MbSoftLab.TemplateEngine.Core.csproj | 2 +- .../MbSoftlab.TemplateEngine.Core.Demo.csproj | 3 +- MbSoftlab.TemplateEngine.Core.Demo/Program.cs | 103 ++++++++++-------- 4 files changed, 63 insertions(+), 53 deletions(-) diff --git a/MbSoftLab.TemplateEngine.Core.Tests/MbSoftLab.TemplateEngine.Core.Tests.csproj b/MbSoftLab.TemplateEngine.Core.Tests/MbSoftLab.TemplateEngine.Core.Tests.csproj index 7501a7f..7dfaf19 100644 --- a/MbSoftLab.TemplateEngine.Core.Tests/MbSoftLab.TemplateEngine.Core.Tests.csproj +++ b/MbSoftLab.TemplateEngine.Core.Tests/MbSoftLab.TemplateEngine.Core.Tests.csproj @@ -1,15 +1,15 @@ - netcoreapp3.1 + net8.0 false - - - + + + diff --git a/MbSoftLab.TemplateEngine.Core/MbSoftLab.TemplateEngine.Core.csproj b/MbSoftLab.TemplateEngine.Core/MbSoftLab.TemplateEngine.Core.csproj index 53c804a..85a8e76 100644 --- a/MbSoftLab.TemplateEngine.Core/MbSoftLab.TemplateEngine.Core.csproj +++ b/MbSoftLab.TemplateEngine.Core/MbSoftLab.TemplateEngine.Core.csproj @@ -1,7 +1,7 @@ - netcoreapp3.1 + net8.0 1.0.8.2 1.0.8.2 1.0.8 diff --git a/MbSoftlab.TemplateEngine.Core.Demo/MbSoftlab.TemplateEngine.Core.Demo.csproj b/MbSoftlab.TemplateEngine.Core.Demo/MbSoftlab.TemplateEngine.Core.Demo.csproj index ad4d8f4..d7f13de 100644 --- a/MbSoftlab.TemplateEngine.Core.Demo/MbSoftlab.TemplateEngine.Core.Demo.csproj +++ b/MbSoftlab.TemplateEngine.Core.Demo/MbSoftlab.TemplateEngine.Core.Demo.csproj @@ -2,7 +2,8 @@ Exe - netcoreapp3.1 + net8.0 + enable RazorSdk true true diff --git a/MbSoftlab.TemplateEngine.Core.Demo/Program.cs b/MbSoftlab.TemplateEngine.Core.Demo/Program.cs index 97ceb05..7593261 100644 --- a/MbSoftlab.TemplateEngine.Core.Demo/Program.cs +++ b/MbSoftlab.TemplateEngine.Core.Demo/Program.cs @@ -1,62 +1,71 @@ using MbSoftLab.TemplateEngine.Core; +using MbSoftLab.TemplateEngine.Core.Demo; using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; +using System.Runtime.InteropServices; +using System.Threading.Tasks; -namespace MbSoftLab.TemplateEngine.Core.Demo +Person testModel = new Person { - class Program + FirstName = "Justin", + LastName = "LastName", + Tags = new List { "Tag1", "Tag2", "Tag3" }, + Address = new Address { - static void Main(string[] args) + Street = "Straße", + PostCode = "7872" + }, + Orders = new List + { + new() { - Person testModel = new Person() + Id = 1, + Products = new List { - FirstName = "Justin", - LastName = "LastName", - Tags = new List() { "Tag1", "Tag2", "Tag3" }, - Address=new Address() - { - Street="Straße", - PostCode="7872" - }, - Orders=new List() - { - new Order() - { - Id=1, - Products=new List() - { - new Product() - { - ProductName="Product1", - Price=150 - }, - new Product() - { - ProductName="Product2", - Price=50 - } - } - } - } - - }; - - + new() { ProductName = "Product1", Price = 150 }, + new() { ProductName = "Product2", Price = 50 } + } + } + } +}; - ITemplateEngine templateEngine = new RazorTemplateEngine(); - templateEngine.LoadTemplateFromFile("TestModel.cshtml"); - string templateFileContent = templateEngine.CreateStringFromTemplate(testModel); - Console.WriteLine(); - Console.WriteLine(templateFileContent); +ITemplateEngine templateEngine = new RazorTemplateEngine(); +templateEngine.LoadTemplateFromFile("TestModel.cshtml"); +var templateFileContent = templateEngine.CreateStringFromTemplate(testModel); +Console.WriteLine(); +Console.WriteLine(templateFileContent); - var htmlFileName = Path.Combine(Path.GetTempPath(), "temp.html"); - File.WriteAllText(htmlFileName, templateFileContent); - Process.Start(@"cmd.exe ", $@"/c {htmlFileName}"); - Console.ReadLine(); +var htmlFileName = Path.Combine(Path.GetTempPath(), "temp.html"); +await File.WriteAllTextAsync(htmlFileName, templateFileContent); +OpenInDefaultBrowser(htmlFileName); - +void OpenInDefaultBrowser(string filePath) +{ + try + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + Process.Start(new ProcessStartInfo + { + FileName = "cmd", + Arguments = $"/c start \"\" \"{filePath}\"", + CreateNoWindow = true + }); + } + else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + { + Process.Start("open", filePath); } + else + { + Process.Start("xdg-open", filePath); + } + } + catch (Exception ex) + { + Console.WriteLine($"Konnte Browser nicht öffnen: {ex.Message}"); + Console.WriteLine($"Pfad: {filePath}"); } -} +} \ No newline at end of file From 60cba34b6a8d743e4ca1bd927adb4ea035bc9b6a Mon Sep 17 00:00:00 2001 From: Justin <50733221+jupre003@users.noreply.github.com> Date: Fri, 5 Dec 2025 22:43:31 +0000 Subject: [PATCH 23/28] =?UTF-8?q?Aktualisiere=20CI/CD-Workflows=20auf=20.N?= =?UTF-8?q?ET=208.0=20und=20verbessere=20die=20Matrix-Strategie=20f=C3=BCr?= =?UTF-8?q?=20plattform=C3=BCbergreifende=20Builds?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/BuildFromDevelop.yml | 20 +++++++++++--------- .github/workflows/BuildFromMaster.yml | 20 +++++++++++--------- .github/workflows/Release.yml | 15 +++++++-------- 3 files changed, 29 insertions(+), 26 deletions(-) diff --git a/.github/workflows/BuildFromDevelop.yml b/.github/workflows/BuildFromDevelop.yml index 0bf746b..33b060f 100644 --- a/.github/workflows/BuildFromDevelop.yml +++ b/.github/workflows/BuildFromDevelop.yml @@ -9,18 +9,20 @@ on: jobs: build: - runs-on: windows-latest + strategy: + matrix: + os: [ubuntu-latest, windows-latest] + runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v2 - - name: Setup .NET Core - uses: actions/setup-dotnet@v1 + - uses: actions/checkout@v4 + - name: Setup .NET + uses: actions/setup-dotnet@v4 with: - dotnet-version: 3.1.301 - - name: Install dependencies - run: | - nuget sources add -name "NuGet official package source" -Source https://api.nuget.org/v3/index.json - dotnet restore + dotnet-version: 8.0.x + cache: true + - name: Restore + run: dotnet restore - name: Build run: dotnet build --configuration Release --no-restore - name: Test diff --git a/.github/workflows/BuildFromMaster.yml b/.github/workflows/BuildFromMaster.yml index 99ce2ed..44af805 100644 --- a/.github/workflows/BuildFromMaster.yml +++ b/.github/workflows/BuildFromMaster.yml @@ -9,18 +9,20 @@ on: jobs: build: - runs-on: windows-latest + strategy: + matrix: + os: [ubuntu-latest, windows-latest] + runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v2 - - name: Setup .NET Core - uses: actions/setup-dotnet@v1 + - uses: actions/checkout@v4 + - name: Setup .NET + uses: actions/setup-dotnet@v4 with: - dotnet-version: 3.1.301 - - name: Install dependencies - run: | - nuget sources add -name "NuGet official package source" -Source https://api.nuget.org/v3/index.json - dotnet restore + dotnet-version: 8.0.x + cache: true + - name: Restore + run: dotnet restore - name: Build run: dotnet build --configuration Release --no-restore - name: Test diff --git a/.github/workflows/Release.yml b/.github/workflows/Release.yml index 49559df..284c545 100644 --- a/.github/workflows/Release.yml +++ b/.github/workflows/Release.yml @@ -9,15 +9,14 @@ jobs: publish-nuget: runs-on: windows-latest steps: - - uses: actions/checkout@v2 - - name: Setup .NET Core - uses: actions/setup-dotnet@v1 + - uses: actions/checkout@v4 + - name: Setup .NET + uses: actions/setup-dotnet@v4 with: - dotnet-version: 3.1.301 - - name: Install dependencies - run: | - nuget sources add -name "NuGet official package source" -Source https://api.nuget.org/v3/index.json - dotnet restore + dotnet-version: 8.0.x + cache: true + - name: Restore + run: dotnet restore - name: Build run: dotnet build --configuration Release --no-restore - name: Publish to NuGet From 5c37e68b63e4bde441d4cef3f6de619bb6a6626b Mon Sep 17 00:00:00 2001 From: Justin <50733221+jupre003@users.noreply.github.com> Date: Fri, 5 Dec 2025 22:45:34 +0000 Subject: [PATCH 24/28] =?UTF-8?q?=C3=84ndere=20den=20Ver=C3=B6ffentlichung?= =?UTF-8?q?sprozess:=20Entferne=20die=20NuGet-Publish-Aktion=20und=20erset?= =?UTF-8?q?ze=20sie=20durch=20dotnet=20pack=20und=20dotnet=20nuget=20push?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Release.yml | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/.github/workflows/Release.yml b/.github/workflows/Release.yml index 284c545..ac522ea 100644 --- a/.github/workflows/Release.yml +++ b/.github/workflows/Release.yml @@ -19,11 +19,7 @@ jobs: run: dotnet restore - name: Build run: dotnet build --configuration Release --no-restore - - name: Publish to NuGet - uses: brandedoutcast/publish-nuget@v2 - with: - PROJECT_FILE_PATH: MbSoftLab.TemplateEngine.Core/MbSoftLab.TemplateEngine.Core.csproj - PACKAGE_NAME: Core - VERSION_REGEX: '^\s*(.*)<\/PackageVersion>\s*$' - TAG_FORMAT: 'v*' - NUGET_KEY: ${{secrets.NUGET_API_KEY}} + - name: Pack + run: dotnet pack MbSoftLab.TemplateEngine.Core/MbSoftLab.TemplateEngine.Core.csproj --configuration Release --no-restore -o ./artifacts + - name: Push to NuGet + run: dotnet nuget push ./artifacts/*.nupkg --api-key ${{ secrets.NUGET_API_KEY }} --source https://api.nuget.org/v3/index.json --skip-duplicate From f37f91692091a2c252c1a1081b80fc9aef9508ea Mon Sep 17 00:00:00 2001 From: Justin <50733221+jupre003@users.noreply.github.com> Date: Fri, 5 Dec 2025 22:53:58 +0000 Subject: [PATCH 25/28] bum verionnumber to 1.1.0 --- .../MbSoftLab.TemplateEngine.Core.csproj | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/MbSoftLab.TemplateEngine.Core/MbSoftLab.TemplateEngine.Core.csproj b/MbSoftLab.TemplateEngine.Core/MbSoftLab.TemplateEngine.Core.csproj index 85a8e76..4601007 100644 --- a/MbSoftLab.TemplateEngine.Core/MbSoftLab.TemplateEngine.Core.csproj +++ b/MbSoftLab.TemplateEngine.Core/MbSoftLab.TemplateEngine.Core.csproj @@ -2,10 +2,10 @@ net8.0 - 1.0.8.2 - 1.0.8.2 - 1.0.8 - 1.0.8-preview2 + 1.1.0.0 + 1.1.0.0 + 1.1.0 + 1.1.0-preview This TemplateEngine can replace values from Classpropertys and methods in simple stringtemplates with a very good performance. The Engine supports the RazorLanguage for creating complex html templates. Documentation.xml true @@ -15,7 +15,7 @@ MbSoftLab MbSoftLab MIT - © 2021 MbSoftLab + © 2021 - 2025 MbSoftLab MbSoftLabLogo.png https://github.com/mbsoftlab/MbSoftLab.TemplateEngine.Core From e2c7df3cb9eb00a23b270b0bfada044183e4d767 Mon Sep 17 00:00:00 2001 From: Justin <50733221+jupre003@users.noreply.github.com> Date: Sat, 6 Dec 2025 14:24:13 +0000 Subject: [PATCH 26/28] Migrate to filescoped nammespaces --- .../IPlaceholderValueRaplacer.cs | 15 +- .../ITemplateEngine.cs | 27 +- .../ITemplateEngineConfig.cs | 37 ++- .../PlaceholderValueRaplacer.cs | 109 ++++---- .../RazorTemplateEngine.cs | 140 +++++----- .../ReplacementActionCollection.cs | 36 +-- .../TemplateDataModel.cs | 16 +- .../TemplateDataModelProcessor.cs | 133 +++++---- .../TemplateEngine.cs | 259 +++++++++--------- .../TemplateEngineConfig.cs | 43 ++- .../TemplateEngineExtensions.cs | 35 ++- 11 files changed, 424 insertions(+), 426 deletions(-) diff --git a/MbSoftLab.TemplateEngine.Core/IPlaceholderValueRaplacer.cs b/MbSoftLab.TemplateEngine.Core/IPlaceholderValueRaplacer.cs index a3d35a0..6d37e59 100644 --- a/MbSoftLab.TemplateEngine.Core/IPlaceholderValueRaplacer.cs +++ b/MbSoftLab.TemplateEngine.Core/IPlaceholderValueRaplacer.cs @@ -1,12 +1,11 @@ using System; using System.Globalization; -namespace MbSoftLab.TemplateEngine.Core +namespace MbSoftLab.TemplateEngine.Core; + +interface IPlaceholderValueRaplacer { - interface IPlaceholderValueRaplacer - { - void ReplacePlaceholderWithValue(Type valueType, string placeholderValueName, object value); - string OutputString { get; } - CultureInfo CultureInfo { get; set; } - } -} + void ReplacePlaceholderWithValue(Type valueType, string placeholderValueName, object value); + string OutputString { get; } + CultureInfo CultureInfo { get; set; } +} \ No newline at end of file diff --git a/MbSoftLab.TemplateEngine.Core/ITemplateEngine.cs b/MbSoftLab.TemplateEngine.Core/ITemplateEngine.cs index 26f81fa..33c6d4f 100644 --- a/MbSoftLab.TemplateEngine.Core/ITemplateEngine.cs +++ b/MbSoftLab.TemplateEngine.Core/ITemplateEngine.cs @@ -1,18 +1,17 @@ using System.Globalization; -namespace MbSoftLab.TemplateEngine.Core +namespace MbSoftLab.TemplateEngine.Core; + +public interface ITemplateEngine { - public interface ITemplateEngine - { - string CloseingDelimiter { get; set; } - ITemplateEngineConfig Config { get; set; } - CultureInfo CultureInfo { get; set; } - string NullStringValue { get; set; } - string OpeningDelimiter { get; set; } - T TemplateDataModel { get; set; } - string TemplateString { get; set; } - string CreateStringFromTemplate(string stringTemplate = null); - string CreateStringFromTemplate(T templateDataModel); - string CreateStringFromTemplate(T templateDataModel, string stringTemplate); - } + string CloseingDelimiter { get; set; } + ITemplateEngineConfig Config { get; set; } + CultureInfo CultureInfo { get; set; } + string NullStringValue { get; set; } + string OpeningDelimiter { get; set; } + T TemplateDataModel { get; set; } + string TemplateString { get; set; } + string CreateStringFromTemplate(string stringTemplate = null); + string CreateStringFromTemplate(T templateDataModel); + string CreateStringFromTemplate(T templateDataModel, string stringTemplate); } \ No newline at end of file diff --git a/MbSoftLab.TemplateEngine.Core/ITemplateEngineConfig.cs b/MbSoftLab.TemplateEngine.Core/ITemplateEngineConfig.cs index bc00b5c..5b21549 100644 --- a/MbSoftLab.TemplateEngine.Core/ITemplateEngineConfig.cs +++ b/MbSoftLab.TemplateEngine.Core/ITemplateEngineConfig.cs @@ -1,22 +1,21 @@ using System.Globalization; -namespace MbSoftLab.TemplateEngine.Core +namespace MbSoftLab.TemplateEngine.Core; + +/// +/// +/// +public interface ITemplateEngineConfig : ITemplateEngineConfig { } +/// +/// +/// +/// +public interface ITemplateEngineConfig { - /// - /// - /// - public interface ITemplateEngineConfig : ITemplateEngineConfig { } - /// - /// - /// - /// - public interface ITemplateEngineConfig - { - string OpeningDelimiter { get; set; } - string CloseingDelimiter { get; set; } - string TemplateString { get; set; } - T TemplateDataModel { get; set; } - string NullStringValue { get; set; } - CultureInfo CultureInfo { get; set; } - } -} + string OpeningDelimiter { get; set; } + string CloseingDelimiter { get; set; } + string TemplateString { get; set; } + T TemplateDataModel { get; set; } + string NullStringValue { get; set; } + CultureInfo CultureInfo { get; set; } +} \ No newline at end of file diff --git a/MbSoftLab.TemplateEngine.Core/PlaceholderValueRaplacer.cs b/MbSoftLab.TemplateEngine.Core/PlaceholderValueRaplacer.cs index 6ebbec1..81cc69b 100644 --- a/MbSoftLab.TemplateEngine.Core/PlaceholderValueRaplacer.cs +++ b/MbSoftLab.TemplateEngine.Core/PlaceholderValueRaplacer.cs @@ -1,62 +1,61 @@ using System; using System.Globalization; -namespace MbSoftLab.TemplateEngine.Core -{ - class PlaceholderValueRaplacer : IPlaceholderValueRaplacer - { - string _outputString; - readonly string _nullStringValue; - public string OutputString => _outputString; - public CultureInfo CultureInfo { get; set; } = CultureInfo.CreateSpecificCulture("en-US"); +namespace MbSoftLab.TemplateEngine.Core; - private ReplacementActionCollection _replacementActionCollection = new ReplacementActionCollection(); - public PlaceholderValueRaplacer(string outputString, string nullStringValue) - { - _outputString = outputString; - _nullStringValue = nullStringValue; - RegisterReplacementActions(); - } - private void RegisterReplacementActions() - { - _replacementActionCollection - .AddReplacementAction(typeof(string), (placeholderValueName, value) => ReplaceNullableStringValueInOutputString(placeholderValueName, (string)value)) - .AddReplacementAction(typeof(byte), (placeholderValueName, value) => ReplaceValueInOutputString(placeholderValueName, (byte)value)) - .AddReplacementAction(typeof(short), (placeholderValueName, value) => ReplaceValueInOutputString(placeholderValueName, (short)value)) - .AddReplacementAction(typeof(ushort), (placeholderValueName, value) => ReplaceValueInOutputString(placeholderValueName, (ushort)value)) - .AddReplacementAction(typeof(long), (placeholderValueName, value) => ReplaceValueInOutputString(placeholderValueName, (long)value)) - .AddReplacementAction(typeof(ulong), (placeholderValueName, value) => ReplaceValueInOutputString(placeholderValueName, (ulong)value)) - .AddReplacementAction(typeof(sbyte), (placeholderValueName, value) => ReplaceValueInOutputString(placeholderValueName, (sbyte)value)) - .AddReplacementAction(typeof(char), (placeholderValueName, value) => ReplaceValueInOutputString(placeholderValueName, (char)value)) - .AddReplacementAction(typeof(UInt16), (placeholderValueName, value) => ReplaceValueInOutputString(placeholderValueName, (UInt16)value)) - .AddReplacementAction(typeof(UInt32), (placeholderValueName, value) => ReplaceValueInOutputString(placeholderValueName, (UInt32)value)) - .AddReplacementAction(typeof(UInt64), (placeholderValueName, value) => ReplaceValueInOutputString(placeholderValueName, (UInt64)value)) - .AddReplacementAction(typeof(Int16), (placeholderValueName, value) => ReplaceValueInOutputString(placeholderValueName, (Int16)value)) - .AddReplacementAction(typeof(Int32), (placeholderValueName, value) => ReplaceValueInOutputString(placeholderValueName, (Int32)value)) - .AddReplacementAction(typeof(Int64), (placeholderValueName, value) => ReplaceValueInOutputString(placeholderValueName, (Int64)value)) - .AddReplacementAction(typeof(Decimal), (placeholderValueName, value) => ReplaceValueInOutputString(placeholderValueName, (Decimal)value)) - .AddReplacementAction(typeof(Double), (placeholderValueName, value) => ReplaceValueInOutputString(placeholderValueName, (double)value)) - .AddReplacementAction(typeof(DateTime), (placeholderValueName, value) => ReplaceValueInOutputString(placeholderValueName, (DateTime)value)) - .AddReplacementAction(typeof(Boolean), (placeholderValueName, value) => ReplaceValueInOutputString(placeholderValueName, ((bool)value))); - } - private void ReplaceValueInOutputString(string placeholderValueName, object value) - { - string replacementForCulture = Convert.ToString(value, CultureInfo); - _outputString = _outputString.Replace(placeholderValueName, replacementForCulture); - } - private void ReplaceNullableStringValueInOutputString(string placeholderValueName, object value) - { - if (value == null) - _outputString = _outputString.Replace(placeholderValueName, _nullStringValue); - else - _outputString = _outputString.Replace(placeholderValueName, (String)value); - } - public void ReplacePlaceholderWithValue(Type valueType, string placeholderValueName, object value) - { - if (IsNoCollection(valueType)) - _replacementActionCollection.InvokeReplacementActionForType(valueType, placeholderValueName, value); - } +class PlaceholderValueRaplacer : IPlaceholderValueRaplacer +{ + string _outputString; + readonly string _nullStringValue; + public string OutputString => _outputString; + public CultureInfo CultureInfo { get; set; } = CultureInfo.CreateSpecificCulture("en-US"); - private bool IsNoCollection(Type valueType) => valueType.FullName.Contains("System.Collections.Generic") == false; + private ReplacementActionCollection _replacementActionCollection = new ReplacementActionCollection(); + public PlaceholderValueRaplacer(string outputString, string nullStringValue) + { + _outputString = outputString; + _nullStringValue = nullStringValue; + RegisterReplacementActions(); } + private void RegisterReplacementActions() + { + _replacementActionCollection + .AddReplacementAction(typeof(string), (placeholderValueName, value) => ReplaceNullableStringValueInOutputString(placeholderValueName, (string)value)) + .AddReplacementAction(typeof(byte), (placeholderValueName, value) => ReplaceValueInOutputString(placeholderValueName, (byte)value)) + .AddReplacementAction(typeof(short), (placeholderValueName, value) => ReplaceValueInOutputString(placeholderValueName, (short)value)) + .AddReplacementAction(typeof(ushort), (placeholderValueName, value) => ReplaceValueInOutputString(placeholderValueName, (ushort)value)) + .AddReplacementAction(typeof(long), (placeholderValueName, value) => ReplaceValueInOutputString(placeholderValueName, (long)value)) + .AddReplacementAction(typeof(ulong), (placeholderValueName, value) => ReplaceValueInOutputString(placeholderValueName, (ulong)value)) + .AddReplacementAction(typeof(sbyte), (placeholderValueName, value) => ReplaceValueInOutputString(placeholderValueName, (sbyte)value)) + .AddReplacementAction(typeof(char), (placeholderValueName, value) => ReplaceValueInOutputString(placeholderValueName, (char)value)) + .AddReplacementAction(typeof(UInt16), (placeholderValueName, value) => ReplaceValueInOutputString(placeholderValueName, (UInt16)value)) + .AddReplacementAction(typeof(UInt32), (placeholderValueName, value) => ReplaceValueInOutputString(placeholderValueName, (UInt32)value)) + .AddReplacementAction(typeof(UInt64), (placeholderValueName, value) => ReplaceValueInOutputString(placeholderValueName, (UInt64)value)) + .AddReplacementAction(typeof(Int16), (placeholderValueName, value) => ReplaceValueInOutputString(placeholderValueName, (Int16)value)) + .AddReplacementAction(typeof(Int32), (placeholderValueName, value) => ReplaceValueInOutputString(placeholderValueName, (Int32)value)) + .AddReplacementAction(typeof(Int64), (placeholderValueName, value) => ReplaceValueInOutputString(placeholderValueName, (Int64)value)) + .AddReplacementAction(typeof(Decimal), (placeholderValueName, value) => ReplaceValueInOutputString(placeholderValueName, (Decimal)value)) + .AddReplacementAction(typeof(Double), (placeholderValueName, value) => ReplaceValueInOutputString(placeholderValueName, (double)value)) + .AddReplacementAction(typeof(DateTime), (placeholderValueName, value) => ReplaceValueInOutputString(placeholderValueName, (DateTime)value)) + .AddReplacementAction(typeof(Boolean), (placeholderValueName, value) => ReplaceValueInOutputString(placeholderValueName, ((bool)value))); + } + private void ReplaceValueInOutputString(string placeholderValueName, object value) + { + string replacementForCulture = Convert.ToString(value, CultureInfo); + _outputString = _outputString.Replace(placeholderValueName, replacementForCulture); + } + private void ReplaceNullableStringValueInOutputString(string placeholderValueName, object value) + { + if (value == null) + _outputString = _outputString.Replace(placeholderValueName, _nullStringValue); + else + _outputString = _outputString.Replace(placeholderValueName, (String)value); + } + public void ReplacePlaceholderWithValue(Type valueType, string placeholderValueName, object value) + { + if (IsNoCollection(valueType)) + _replacementActionCollection.InvokeReplacementActionForType(valueType, placeholderValueName, value); + } + + private bool IsNoCollection(Type valueType) => valueType.FullName.Contains("System.Collections.Generic") == false; } \ No newline at end of file diff --git a/MbSoftLab.TemplateEngine.Core/RazorTemplateEngine.cs b/MbSoftLab.TemplateEngine.Core/RazorTemplateEngine.cs index 990f985..dcc6fee 100644 --- a/MbSoftLab.TemplateEngine.Core/RazorTemplateEngine.cs +++ b/MbSoftLab.TemplateEngine.Core/RazorTemplateEngine.cs @@ -1,85 +1,89 @@ using RazorEngineCore; using System; -using System.Collections.Generic; using System.ComponentModel; using System.Globalization; -using System.Text; -namespace MbSoftLab.TemplateEngine.Core +namespace MbSoftLab.TemplateEngine.Core; + +public class RazorTemplateEngine : ITemplateEngine where T : TemplateDataModel { - public class RazorTemplateEngine : ITemplateEngine where T : TemplateDataModel + public string CloseingDelimiter { get { Console.WriteLine($"RazorTemplateEngine has no {nameof(CloseingDelimiter)}"); return ""; } set => Console.WriteLine($"Can not set {nameof(CloseingDelimiter)} for RazorTemplateEngine"); } + ITemplateEngineConfig _config; + public ITemplateEngineConfig Config { - public string CloseingDelimiter { get { Console.WriteLine($"RazorTemplateEngine has no {nameof(CloseingDelimiter)}"); return ""; } set => Console.WriteLine($"Can not set {nameof(CloseingDelimiter)} for RazorTemplateEngine"); } - ITemplateEngineConfig _config; - public ITemplateEngineConfig Config + get => _config; + set { - get => _config; - set - { - _config = value; - this.NullStringValue = _config.NullStringValue; - this.OpeningDelimiter = _config.OpeningDelimiter; - this.CloseingDelimiter = _config.CloseingDelimiter; - this.TemplateDataModel = _config.TemplateDataModel; - this.TemplateString = _config.TemplateString; - this.CultureInfo = _config.CultureInfo; - } + _config = value; + this.NullStringValue = _config.NullStringValue; + this.OpeningDelimiter = _config.OpeningDelimiter; + this.CloseingDelimiter = _config.CloseingDelimiter; + this.TemplateDataModel = _config.TemplateDataModel; + this.TemplateString = _config.TemplateString; + this.CultureInfo = _config.CultureInfo; } - public CultureInfo CultureInfo { get { Console.WriteLine($"{nameof(RazorTemplateEngine)} can not maipulate {nameof(CultureInfo)}"); return null; } set => Console.WriteLine($"{nameof(RazorTemplateEngine)} can not maipulate {nameof(CultureInfo)}"); } + } + public CultureInfo CultureInfo { get { Console.WriteLine($"{nameof(RazorTemplateEngine)} can not maipulate {nameof(CultureInfo)}"); return null; } set => Console.WriteLine($"{nameof(RazorTemplateEngine)} can not maipulate {nameof(CultureInfo)}"); } - public string NullStringValue - { - get => "String.Empty"; - set { Console.WriteLine(new WarningException($"{nameof(RazorTemplateEngine)} can not maipulate {nameof(NullStringValue)}").Message); } - } - public string OpeningDelimiter - { - get - { - Console.WriteLine(new WarningException($"RazorTemplateEngine has no {nameof(OpeningDelimiter)}").Message); - return ""; - } - set - { - Console.WriteLine(new WarningException($"Can not set {nameof(OpeningDelimiter)} for RazorTemplateEngine").Message); - } - } - public T TemplateDataModel { get; set; } - public string TemplateString { get; set; } - IRazorEngine razorEngine; - public RazorTemplateEngine(IRazorEngine razorEngine) - { - this.razorEngine = razorEngine; - } - public RazorTemplateEngine() + public string NullStringValue + { + get => "String.Empty"; + set { Console.WriteLine(new WarningException($"{nameof(RazorTemplateEngine)} can not maipulate {nameof(NullStringValue)}").Message); } + } + + public string OpeningDelimiter + { + get { - razorEngine = new RazorEngine(); + Console.WriteLine(new WarningException($"RazorTemplateEngine has no {nameof(OpeningDelimiter)}").Message); + return ""; } - public RazorTemplateEngine(T dataModel, string templateString) + set { - razorEngine = new RazorEngine(); - TemplateDataModel = dataModel; - TemplateString = templateString; + Console.WriteLine(new WarningException($"Can not set {nameof(OpeningDelimiter)} for RazorTemplateEngine").Message); } - public string CreateStringFromTemplate(string csHtmlTemplate = null) - { - TemplateString = csHtmlTemplate ?? TemplateString; - IRazorEngineCompiledTemplate template = razorEngine.Compile(TemplateString); + } + + public T TemplateDataModel { get; set; } + public string TemplateString { get; set; } + IRazorEngine razorEngine; + + public RazorTemplateEngine(IRazorEngine razorEngine) + { + this.razorEngine = razorEngine; + } + + public RazorTemplateEngine() + { + razorEngine = new RazorEngine(); + } - string result = template.Run(TemplateDataModel); - return result; - } - public string CreateStringFromTemplate(T templateDataModel) - { - TemplateDataModel = templateDataModel; - return CreateStringFromTemplate(); - } + public RazorTemplateEngine(T dataModel, string templateString) + { + razorEngine = new RazorEngine(); + TemplateDataModel = dataModel; + TemplateString = templateString; + } + + public string CreateStringFromTemplate(string csHtmlTemplate = null) + { + TemplateString = csHtmlTemplate ?? TemplateString; + IRazorEngineCompiledTemplate template = razorEngine.Compile(TemplateString); - public string CreateStringFromTemplate(T templateDataModel, string csHtmlTemplate) - { - TemplateDataModel = templateDataModel; - TemplateString = csHtmlTemplate; - return CreateStringFromTemplate(); - } + string result = template.Run(TemplateDataModel); + return result; + } + + public string CreateStringFromTemplate(T templateDataModel) + { + TemplateDataModel = templateDataModel; + return CreateStringFromTemplate(); + } + + public string CreateStringFromTemplate(T templateDataModel, string csHtmlTemplate) + { + TemplateDataModel = templateDataModel; + TemplateString = csHtmlTemplate; + return CreateStringFromTemplate(); } -} +} \ No newline at end of file diff --git a/MbSoftLab.TemplateEngine.Core/ReplacementActionCollection.cs b/MbSoftLab.TemplateEngine.Core/ReplacementActionCollection.cs index ad6fe00..ec2e6ed 100644 --- a/MbSoftLab.TemplateEngine.Core/ReplacementActionCollection.cs +++ b/MbSoftLab.TemplateEngine.Core/ReplacementActionCollection.cs @@ -1,25 +1,27 @@ using System; using System.Collections.Generic; -namespace MbSoftLab.TemplateEngine.Core +namespace MbSoftLab.TemplateEngine.Core; + +class ReplacementActionCollection { - class ReplacementActionCollection + private Dictionary> replacementActions = new Dictionary>(); + + public ReplacementActionCollection AddReplacementAction(Type type, Action action) { - private Dictionary> replacementActions = new Dictionary>(); - public ReplacementActionCollection AddReplacementAction(Type type, Action action) - { - if (!ReplacementActionForTypeExist(type)) - replacementActions.Add(type.Name, action); + if (!ReplacementActionForTypeExist(type)) + replacementActions.Add(type.Name, action); - return this; - } - public bool ReplacementActionForTypeExist(Type valueType) => replacementActions.ContainsKey(valueType.Name); - public void InvokeReplacementActionForType(Type valueType, string placeholderValueName, object value) - { - if (ReplacementActionForTypeExist(valueType)) - replacementActions[valueType.Name].Invoke(placeholderValueName, value); - else - throw new NotSupportedException($"Type '{valueType}' not supported by TemplateEngine.createStringFromTemplate()."); - } + return this; + } + + public bool ReplacementActionForTypeExist(Type valueType) => replacementActions.ContainsKey(valueType.Name); + + public void InvokeReplacementActionForType(Type valueType, string placeholderValueName, object value) + { + if (ReplacementActionForTypeExist(valueType)) + replacementActions[valueType.Name].Invoke(placeholderValueName, value); + else + throw new NotSupportedException($"Type '{valueType}' not supported by TemplateEngine.createStringFromTemplate()."); } } \ No newline at end of file diff --git a/MbSoftLab.TemplateEngine.Core/TemplateDataModel.cs b/MbSoftLab.TemplateEngine.Core/TemplateDataModel.cs index efe1ebe..a61384a 100644 --- a/MbSoftLab.TemplateEngine.Core/TemplateDataModel.cs +++ b/MbSoftLab.TemplateEngine.Core/TemplateDataModel.cs @@ -1,15 +1,15 @@ using RazorEngineCore; using System.Text.Json.Serialization; -namespace MbSoftLab.TemplateEngine.Core +namespace MbSoftLab.TemplateEngine.Core; + +public class TemplateDataModel : RazorEngineTemplateBase { - public class TemplateDataModel : RazorEngineTemplateBase + [JsonIgnore] + public new T Model { get; set; } + + public string GetNullstringValue() { - [JsonIgnore] - public new T Model { get; set; } - public string GetNullstringValue() - { - return this.GetNullstringValue(); - } + return this.GetNullstringValue(); } } \ No newline at end of file diff --git a/MbSoftLab.TemplateEngine.Core/TemplateDataModelProcessor.cs b/MbSoftLab.TemplateEngine.Core/TemplateDataModelProcessor.cs index f37ebc5..c251345 100644 --- a/MbSoftLab.TemplateEngine.Core/TemplateDataModelProcessor.cs +++ b/MbSoftLab.TemplateEngine.Core/TemplateDataModelProcessor.cs @@ -3,85 +3,84 @@ using System.Linq; using System.Reflection; -namespace MbSoftLab.TemplateEngine.Core +namespace MbSoftLab.TemplateEngine.Core; + +class TemplateDataModelProcessor { - class TemplateDataModelProcessor + string _openingDelimiter, _closeingDelimiter; + private List _methodBlacklist = new List() { "ToString", "GetType", "Equals", "GetHashCode" }; + + IPlaceholderValueRaplacer _placeholderValueRaplacer; + + private void AddMethodsFromTemplateDataModelBaseClassToBlacklist() + { + new TemplateDataModel().GetType() + .GetMethods().ToList() + .ForEach(method => _methodBlacklist.Add(method.Name)); + } + public TemplateDataModelProcessor(string openingDelimiter, string closeingDelimiter, IPlaceholderValueRaplacer placeholderValueRaplacer) + { + _openingDelimiter = openingDelimiter; + _closeingDelimiter = closeingDelimiter; + _placeholderValueRaplacer = placeholderValueRaplacer; + AddMethodsFromTemplateDataModelBaseClassToBlacklist(); + } + public void ProcessTemplateDataModell(object templateDataModel) { - string _openingDelimiter, _closeingDelimiter; - private List _methodBlacklist = new List() { "ToString", "GetType", "Equals", "GetHashCode" }; + ProcessTemplateDataModelClassMethods(templateDataModel); + ProcessTemplateDataModelClassPropertys(templateDataModel); + } + private void ProcessTemplateDataModelClassMethods(object templateDataModel) + { + Type t = templateDataModel.GetType(); + List methodInfos = t.GetMethods().Where(mi => mi.IsSpecialName == false + && !_methodBlacklist.Contains(mi.Name) + ).ToList(); - IPlaceholderValueRaplacer _placeholderValueRaplacer; - - private void AddMethodsFromTemplateDataModelBaseClassToBlacklist() - { - new TemplateDataModel().GetType() - .GetMethods().ToList() - .ForEach(method=>_methodBlacklist.Add(method.Name)); - } - public TemplateDataModelProcessor(string openingDelimiter, string closeingDelimiter, IPlaceholderValueRaplacer placeholderValueRaplacer) - { - _openingDelimiter = openingDelimiter; - _closeingDelimiter = closeingDelimiter; - _placeholderValueRaplacer = placeholderValueRaplacer; - AddMethodsFromTemplateDataModelBaseClassToBlacklist(); - } - public void ProcessTemplateDataModell(object templateDataModel) + foreach (MethodInfo methodInfo in methodInfos) { - ProcessTemplateDataModelClassMethods(templateDataModel); - ProcessTemplateDataModelClassPropertys(templateDataModel); - } - private void ProcessTemplateDataModelClassMethods(object templateDataModel) - { - Type t = templateDataModel.GetType(); - List methodInfos = t.GetMethods().Where(mi => mi.IsSpecialName == false - && !_methodBlacklist.Contains(mi.Name) - ).ToList(); - - foreach (MethodInfo methodInfo in methodInfos) + if (methodInfo.IsPublic) { - if (methodInfo.IsPublic) + var parameters = methodInfo.GetParameters(); + if (parameters.Count() > 0) continue; // TODO: Methoden mit Parameter unterstüzen. Dazu über Methodenname die angegebenen Parameter in der HTML file auslesen + + var instance = Activator.CreateInstance(t); + object methodValue = methodInfo.Invoke(instance, parameters); + Type methodValueType = methodInfo.ReturnType; + string methodName = _openingDelimiter + methodInfo.Name + "()" + _closeingDelimiter; + try { - var parameters = methodInfo.GetParameters(); - if (parameters.Count() > 0) continue; // TODO: Methoden mit Parameter unterstüzen. Dazu über Methodenname die angegebenen Parameter in der HTML file auslesen - - var instance = Activator.CreateInstance(t); - object methodValue = methodInfo.Invoke(instance, parameters); - Type methodValueType = methodInfo.ReturnType; - string methodName = _openingDelimiter + methodInfo.Name + "()" + _closeingDelimiter; - try - { - _placeholderValueRaplacer.ReplacePlaceholderWithValue(methodValueType, methodName, methodValue); - } - catch (Exception ex) - { - throw ex; - } + _placeholderValueRaplacer.ReplacePlaceholderWithValue(methodValueType, methodName, methodValue); + } + catch (Exception ex) + { + throw ex; } } } - private void ProcessTemplateDataModelClassPropertys(object templateDataModel) - { - Type t = templateDataModel.GetType(); - PropertyInfo[] propertyInfos = t.GetProperties(); + } + private void ProcessTemplateDataModelClassPropertys(object templateDataModel) + { + Type t = templateDataModel.GetType(); + PropertyInfo[] propertyInfos = t.GetProperties(); - foreach (PropertyInfo propertyInfo in propertyInfos) + foreach (PropertyInfo propertyInfo in propertyInfos) + { + if ((propertyInfo.CanRead)) { - if ((propertyInfo.CanRead)) - { - object propertyValue = propertyInfo.GetValue(templateDataModel, null); - string propertyName = _openingDelimiter + propertyInfo.Name + _closeingDelimiter; - Type propertyValueType = null; + object propertyValue = propertyInfo.GetValue(templateDataModel, null); + string propertyName = _openingDelimiter + propertyInfo.Name + _closeingDelimiter; + Type propertyValueType = null; - if (propertyValue != null) propertyValueType = propertyValue?.GetType(); - else propertyValueType = typeof(string); - try - { - _placeholderValueRaplacer.ReplacePlaceholderWithValue(propertyValueType, propertyName, propertyValue); - } - catch (Exception ex) - { - throw ex; - } + if (propertyValue != null) propertyValueType = propertyValue?.GetType(); + else propertyValueType = typeof(string); + try + { + _placeholderValueRaplacer.ReplacePlaceholderWithValue(propertyValueType, propertyName, propertyValue); + } + catch (Exception ex) + { + throw ex; } } } diff --git a/MbSoftLab.TemplateEngine.Core/TemplateEngine.cs b/MbSoftLab.TemplateEngine.Core/TemplateEngine.cs index 5b556c0..784af34 100644 --- a/MbSoftLab.TemplateEngine.Core/TemplateEngine.cs +++ b/MbSoftLab.TemplateEngine.Core/TemplateEngine.cs @@ -3,160 +3,159 @@ using System.Globalization; using System.Text.Json; -namespace MbSoftLab.TemplateEngine.Core +namespace MbSoftLab.TemplateEngine.Core; + +/// +/// A simple StringTemplateengine for .NET.

+/// See for more details +///
+public class TemplateEngine : TemplateEngine, ITemplateEngine +{ + #region --- CONSTRUCTORS + public TemplateEngine(object templateDataModel, string stringTemplate) : base(templateDataModel, stringTemplate) + { + + } + public TemplateEngine(object templateDataModel) : base(templateDataModel) + { + + } + + public TemplateEngine() + { + + } + #endregion +} + +public class TemplateEngine : ITemplateEngine { + private string _outputString; + + #region --- PUBLIC PROPERTYS + /// + /// Beginning Char for a PlaceholderProperty. The Defaultvalue ist "${". + /// + public string OpeningDelimiter { get => _openingDelimiter; set => _openingDelimiter = value.Trim(); } + private string _openingDelimiter = "${"; /// - /// A simple StringTemplateengine for .NET.

- /// See for more details + /// Ending Char for a PlaceholderProperty. Der Default ist "}". ///
- public class TemplateEngine : TemplateEngine, ITemplateEngine + public string CloseingDelimiter { get => _closeingDelimiter; set => _closeingDelimiter = value.Trim(); } + private string _closeingDelimiter = "}"; + /// + /// Model with propertys to fill ${PlaceholderPropertys} in the template. The propertynames at DataModel has to be equal with ${Placeholder} + /// + public T TemplateDataModel { get => _templateDataModel; set => _templateDataModel = value; } + T _templateDataModel; + /// + /// The Templatestring with ${PlaceholderPropertys} + /// + public string TemplateString { - #region --- CONSTRUCTORS - public TemplateEngine(object templateDataModel, string stringTemplate):base(templateDataModel, stringTemplate) + get => _templateString; + set { - + if (value != null && value != _templateString) + _templateString = value; } - public TemplateEngine(object templateDataModel):base(templateDataModel) - { - - } - - public TemplateEngine() - { - - } - #endregion } + string _templateString; + /// + /// Get or Set the string for NULL-Values. Default = NULL. + /// + public string NullStringValue { get => _nullStringValue; set => _nullStringValue = value; } + string _nullStringValue = "NULL"; + public CultureInfo CultureInfo { get; set; } = CultureInfo.CreateSpecificCulture("en-US"); - public class TemplateEngine : ITemplateEngine + public ITemplateEngineConfig Config { - private string _outputString; - - #region --- PUBLIC PROPERTYS - /// - /// Beginning Char for a PlaceholderProperty. The Defaultvalue ist "${". - /// - public string OpeningDelimiter { get => _openingDelimiter; set => _openingDelimiter = value.Trim(); } - private string _openingDelimiter = "${"; - /// - /// Ending Char for a PlaceholderProperty. Der Default ist "}". - /// - public string CloseingDelimiter { get => _closeingDelimiter; set => _closeingDelimiter = value.Trim(); } - private string _closeingDelimiter = "}"; - /// - /// Model with propertys to fill ${PlaceholderPropertys} in the template. The propertynames at DataModel has to be equal with ${Placeholder} - /// - public T TemplateDataModel { get => _templateDataModel; set => _templateDataModel = value; } - T _templateDataModel; - /// - /// The Templatestring with ${PlaceholderPropertys} - /// - public string TemplateString + get => _config; + set { - get => _templateString; - set - { - if (value != null && value != _templateString) - _templateString = value; - } + _config = value; + this.NullStringValue = _config.NullStringValue; + this.OpeningDelimiter = _config.OpeningDelimiter; + this.CloseingDelimiter = _config.CloseingDelimiter; + this.TemplateDataModel = _config.TemplateDataModel; + this.TemplateString = _config.TemplateString; + this.CultureInfo = _config.CultureInfo; } - string _templateString; - /// - /// Get or Set the string for NULL-Values. Default = NULL. - /// - public string NullStringValue { get => _nullStringValue; set => _nullStringValue = value; } - string _nullStringValue = "NULL"; - public CultureInfo CultureInfo { get; set; } = CultureInfo.CreateSpecificCulture("en-US"); - - public ITemplateEngineConfig Config - { - get => _config; - set - { - _config = value; - this.NullStringValue = _config.NullStringValue; - this.OpeningDelimiter = _config.OpeningDelimiter; - this.CloseingDelimiter = _config.CloseingDelimiter; - this.TemplateDataModel = _config.TemplateDataModel; - this.TemplateString = _config.TemplateString; - this.CultureInfo = _config.CultureInfo; - } - } - private ITemplateEngineConfig _config; - #endregion + } + private ITemplateEngineConfig _config; + #endregion - #region --- CONSTRUCTORS - public TemplateEngine(T templateDataModel, string stringTemplate) - { - _templateDataModel = templateDataModel; - _templateString = stringTemplate; - } - public TemplateEngine(T templateDataModel) - { - _templateDataModel = templateDataModel; - } + #region --- CONSTRUCTORS + public TemplateEngine(T templateDataModel, string stringTemplate) + { + _templateDataModel = templateDataModel; + _templateString = stringTemplate; + } + public TemplateEngine(T templateDataModel) + { + _templateDataModel = templateDataModel; + } - public TemplateEngine() - { + public TemplateEngine() + { - } + } - #endregion + #endregion - /// - /// Replaces all Propertys of templateDataModel in stringTemplate. The Popertynames from templateDataModel a the name of ${Placeholder} have to be equal. - /// Example: public string MyProperty => ${MyProperty} - /// - /// File with Data from TemplateDataModel - public string CreateStringFromTemplate(string stringTemplate = null) - { - try - { - TemplateString = stringTemplate; - return CreateStringFromTemplate(); - } - catch (Exception ex) - { - throw ex; - } - } - /// - /// Replaces all Propertys of templateDataModel in stringTemplate. The Popertynames from templateDataModel a the name of ${Placeholder} have to be equal. - /// Example: public string MyProperty => ${MyProperty} - /// - /// File with Data from TemplateDataModel - public string CreateStringFromTemplate(T templateDataModel, string stringTemplate) + /// + /// Replaces all Propertys of templateDataModel in stringTemplate. The Popertynames from templateDataModel a the name of ${Placeholder} have to be equal. + /// Example: public string MyProperty => ${MyProperty} + /// + /// File with Data from TemplateDataModel + public string CreateStringFromTemplate(string stringTemplate = null) + { + try { TemplateString = stringTemplate; - _templateDataModel = templateDataModel; return CreateStringFromTemplate(); } - /// - /// Replaces all Propertys of templateDataModel in stringTemplate. The Popertynames from templateDataModel a the name of ${Placeholder} have to be equal. - /// Example: public string MyProperty => ${MyProperty} - /// - /// File with Data from TemplateDataModel - public string CreateStringFromTemplate(T templateDataModel) + catch (Exception ex) { - _templateDataModel = templateDataModel; - return CreateStringFromTemplate(); + throw ex; } + } + /// + /// Replaces all Propertys of templateDataModel in stringTemplate. The Popertynames from templateDataModel a the name of ${Placeholder} have to be equal. + /// Example: public string MyProperty => ${MyProperty} + /// + /// File with Data from TemplateDataModel + public string CreateStringFromTemplate(T templateDataModel, string stringTemplate) + { + TemplateString = stringTemplate; + _templateDataModel = templateDataModel; + return CreateStringFromTemplate(); + } + /// + /// Replaces all Propertys of templateDataModel in stringTemplate. The Popertynames from templateDataModel a the name of ${Placeholder} have to be equal. + /// Example: public string MyProperty => ${MyProperty} + /// + /// File with Data from TemplateDataModel + public string CreateStringFromTemplate(T templateDataModel) + { + _templateDataModel = templateDataModel; + return CreateStringFromTemplate(); + } - /// - /// Replaces all Propertys of templateDataModel in stringTemplate. The Popertynames from templateDataModel a the name of ${Placeholder} have to be equal. - /// Example: public string MyProperty => ${MyProperty} - /// - /// File with Data from TemplateDataModel - private string CreateStringFromTemplate() - { - _outputString = _templateString; + /// + /// Replaces all Propertys of templateDataModel in stringTemplate. The Popertynames from templateDataModel a the name of ${Placeholder} have to be equal. + /// Example: public string MyProperty => ${MyProperty} + /// + /// File with Data from TemplateDataModel + private string CreateStringFromTemplate() + { + _outputString = _templateString; - IPlaceholderValueRaplacer placeholderValueRaplacer = new PlaceholderValueRaplacer(_outputString, _nullStringValue); - placeholderValueRaplacer.CultureInfo = CultureInfo; - TemplateDataModelProcessor templateDataModelProcessor = new TemplateDataModelProcessor(_openingDelimiter, _closeingDelimiter, placeholderValueRaplacer); - templateDataModelProcessor.ProcessTemplateDataModell(_templateDataModel); + IPlaceholderValueRaplacer placeholderValueRaplacer = new PlaceholderValueRaplacer(_outputString, _nullStringValue); + placeholderValueRaplacer.CultureInfo = CultureInfo; + TemplateDataModelProcessor templateDataModelProcessor = new TemplateDataModelProcessor(_openingDelimiter, _closeingDelimiter, placeholderValueRaplacer); + templateDataModelProcessor.ProcessTemplateDataModell(_templateDataModel); - return placeholderValueRaplacer.OutputString; - } + return placeholderValueRaplacer.OutputString; } } \ No newline at end of file diff --git a/MbSoftLab.TemplateEngine.Core/TemplateEngineConfig.cs b/MbSoftLab.TemplateEngine.Core/TemplateEngineConfig.cs index 445d0c2..f181e4d 100644 --- a/MbSoftLab.TemplateEngine.Core/TemplateEngineConfig.cs +++ b/MbSoftLab.TemplateEngine.Core/TemplateEngineConfig.cs @@ -1,26 +1,25 @@ using System.Globalization; -namespace MbSoftLab.TemplateEngine.Core +namespace MbSoftLab.TemplateEngine.Core; + +/// +/// +/// +public class TemplateEngineConfig : TemplateEngineConfig { } +/// +/// +/// +public class TemplateEngineConfig : ITemplateEngineConfig { - /// - /// - /// - public class TemplateEngineConfig : TemplateEngineConfig{ } - /// - /// - /// - public class TemplateEngineConfig : ITemplateEngineConfig - { - public CultureInfo CultureInfo { get; set; } = CultureInfo.CreateSpecificCulture("en-US"); - public string OpeningDelimiter { get => _openingDelimiter; set => _openingDelimiter=value.Trim(); } - private string _openingDelimiter; - public string CloseingDelimiter { get => _closeingDelimiter; set => _closeingDelimiter=value.Trim(); } - private string _closeingDelimiter; - public string TemplateString { get => _templateString; set => _templateString=value; } - private string _templateString; - public T TemplateDataModel { get => _templateDataModel; set => _templateDataModel=value; } - private T _templateDataModel; - public string NullStringValue { get => _nullStringValue; set => _nullStringValue=value; } - private string _nullStringValue; - } + public CultureInfo CultureInfo { get; set; } = CultureInfo.CreateSpecificCulture("en-US"); + public string OpeningDelimiter { get => _openingDelimiter; set => _openingDelimiter = value.Trim(); } + private string _openingDelimiter; + public string CloseingDelimiter { get => _closeingDelimiter; set => _closeingDelimiter = value.Trim(); } + private string _closeingDelimiter; + public string TemplateString { get => _templateString; set => _templateString = value; } + private string _templateString; + public T TemplateDataModel { get => _templateDataModel; set => _templateDataModel = value; } + private T _templateDataModel; + public string NullStringValue { get => _nullStringValue; set => _nullStringValue = value; } + private string _nullStringValue; } \ No newline at end of file diff --git a/MbSoftLab.TemplateEngine.Core/TemplateEngineExtensions.cs b/MbSoftLab.TemplateEngine.Core/TemplateEngineExtensions.cs index 709c5d5..30a0152 100644 --- a/MbSoftLab.TemplateEngine.Core/TemplateEngineExtensions.cs +++ b/MbSoftLab.TemplateEngine.Core/TemplateEngineExtensions.cs @@ -1,24 +1,23 @@ using System.Text.Json; -namespace MbSoftLab.TemplateEngine.Core +namespace MbSoftLab.TemplateEngine.Core; + +public static class TemplateEngineExtensions { - public static class TemplateEngineExtensions + /// + /// Load the TemplateDataModel from JSON and builds a String with this Data + /// + public static string CreateStringFromTemplateWithJson(this ITemplateEngine templateEngine, string jsonData) + { + templateEngine.TemplateDataModel = JsonSerializer.Deserialize(jsonData); + return templateEngine.CreateStringFromTemplate(); + } + /// + /// Loads a Templatestring from File + /// + /// Path to File with Templatestring. + public static void LoadTemplateFromFile(this ITemplateEngine templateEngine, string path) { - /// - /// Load the TemplateDataModel from JSON and builds a String with this Data - /// - public static string CreateStringFromTemplateWithJson(this ITemplateEngine templateEngine, string jsonData) - { - templateEngine.TemplateDataModel = JsonSerializer.Deserialize(jsonData); - return templateEngine.CreateStringFromTemplate(); - } - /// - /// Loads a Templatestring from File - /// - /// Path to File with Templatestring. - public static void LoadTemplateFromFile(this ITemplateEngine templateEngine, string path) - { - templateEngine.TemplateString = System.IO.File.ReadAllText(path); - } + templateEngine.TemplateString = System.IO.File.ReadAllText(path); } } \ No newline at end of file From a33163c80a75265a9e2c8fbb50fc838381178982 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Sat, 6 Dec 2025 15:45:21 +0100 Subject: [PATCH 27/28] Add comprehensive German documentation for TemplateEngine.Core (#11) Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: jupre003 <50733221+jupre003@users.noreply.github.com> --- CHANGELOG.md | 55 +++ LICENSE | 21 ++ README.md | 326 ++++++++--------- RELEASENOTES.md | 138 ++++++++ docs/README.md | 237 +++++++++++++ docs/api.md | 643 ++++++++++++++++++++++++++++++++++ docs/architecture.md | 378 ++++++++++++++++++++ docs/development.md | 627 +++++++++++++++++++++++++++++++++ docs/examples.md | 815 +++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 3079 insertions(+), 161 deletions(-) create mode 100644 CHANGELOG.md create mode 100644 LICENSE create mode 100644 RELEASENOTES.md create mode 100644 docs/README.md create mode 100644 docs/api.md create mode 100644 docs/architecture.md create mode 100644 docs/development.md create mode 100644 docs/examples.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..6eaa355 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,55 @@ +# Changelog + +Alle wichtigen Änderungen an diesem Projekt werden in dieser Datei dokumentiert. + +Das Format basiert auf [Keep a Changelog](https://keepachangelog.com/de/1.0.0/), +und dieses Projekt folgt [Semantic Versioning](https://semver.org/lang/de/). + +## [Unveröffentlicht] + +### Geändert +- Veröffentlichungsprozess aktualisiert: NuGet-Publish-Aktion durch `dotnet pack` und `dotnet nuget push` ersetzt (Commit: 5c37e68) + +## [1.0.8-preview2] - Stand: Commit 5c37e68 + +### Hinzugefügt +- RazorTemplateEngine für komplexe HTML-Templates mit Razor-Syntax +- Unterstützung für Razor-Templates mit der `RazorTemplateEngine` Klasse +- `ITemplateEngine` Interface für beide Template-Engine-Implementierungen +- `ITemplateEngineConfig` Interface und `TemplateEngineConfig` Klasse für Konfiguration +- Erweiterungsmethoden `CreateStringFromTemplateWithJson` und `LoadTemplateFromFile` +- Demo-Projekt mit Razor-Template-Beispielen +- Unterstützung für parameterlose öffentliche Methoden im TemplateDataModel (Syntax: `${MethodName()}`) + +### Funktionen +- Einfacher String-basierter Template-Engine (`TemplateEngine` und `TemplateEngine`) +- Razor-basierter Template-Engine (`RazorTemplateEngine`) +- Anpassbare Delimiter (Standard: `${` und `}`) +- Konfigurierbare NULL-Wert-Behandlung (Standard: "NULL") +- Kultur-spezifische Formatierung für Datum und Zahlen (Standard: en-US) +- JSON-Deserialisierung für TemplateDataModel +- Laden von Templates aus Dateien + +### Unterstützte Datentypen +- Primitive Typen: String, Byte, Short, UShort, Long, ULong, SByte, Char +- Numerische Typen: Int16, Int32, Int64, UInt16, UInt32, UInt64, Decimal, Double +- Weitere Typen: DateTime, Boolean + +### Technische Details +- Target Framework: .NET 8.0 +- Assembly Version: 1.0.8.2 +- Package Version: 1.0.8-preview2 +- Abhängigkeit: RazorEngineCore 2020.10.1 + +### Build und CI/CD +- GitHub Actions Workflows für Build (Develop und Master Branch) +- GitHub Actions Workflow für Release und NuGet-Veröffentlichung +- Automatische NuGet-Package-Generierung beim Build + +--- + +## Versions-Historie (Zusammenfassung) + +Die Version 1.0.8-preview2 ist die aktuelle Entwicklungsversion mit Razor-Template-Unterstützung. + +**Commit-Referenz für diese Dokumentation:** 5c37e68 (Basis-Commit für Dokumentation) diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..f13e941 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 MbSoftLab + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index 3f72cfe..7224d65 100644 --- a/README.md +++ b/README.md @@ -1,218 +1,222 @@ -# MbSoftLab.TemplateEngine.Core +# MbSoftLab.TemplateEngine.Core -![BuildFromDevelop](https://github.com/mbsoftlab/MbSoftLab.TemplateEngine.Core/workflows/BuildFromDevelop/badge.svg?branch=develop) ![BuildFromMaster](https://github.com/mbsoftlab/MbSoftLab.TemplateEngine.Core/workflows/BuildFromMaster/badge.svg?branch=master)![Release](https://github.com/mbsoftlab/MbSoftLab.TemplateEngine.Core/workflows/Release/badge.svg) - -*Codequality (master branch)* +[![Build (develop)](https://github.com/mbsoftlab/MbSoftLab.TemplateEngine.Core/workflows/BuildFromDevelop/badge.svg?branch=develop)](https://github.com/mbsoftlab/MbSoftLab.TemplateEngine.Core/actions) +[![Build (master)](https://github.com/mbsoftlab/MbSoftLab.TemplateEngine.Core/workflows/BuildFromMaster/badge.svg?branch=master)](https://github.com/mbsoftlab/MbSoftLab.TemplateEngine.Core/actions) +[![Release](https://github.com/mbsoftlab/MbSoftLab.TemplateEngine.Core/workflows/Release/badge.svg)](https://github.com/mbsoftlab/MbSoftLab.TemplateEngine.Core/actions) [![CodeFactor](https://www.codefactor.io/repository/github/mbsoftlab/mbsoftlab.templateengine.core/badge)](https://www.codefactor.io/repository/github/mbsoftlab/mbsoftlab.templateengine.core) +[![NuGet](https://img.shields.io/nuget/v/MbSoftLab.TemplateEngine.Core.svg)](https://www.nuget.org/packages/MbSoftLab.TemplateEngine.Core/) +[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE) -*Codequality (develop branch)* -[![CodeFactor](https://www.codefactor.io/repository/github/mbsoftlab/mbsoftlab.templateengine.core/badge/develop)](https://www.codefactor.io/repository/github/mbsoftlab/mbsoftlab.templateengine.core/overview/develop) -```csharp -namespace MbSoftLab.TemplateEngine.Core -{ - public class TemplateEngine : TemplateEngine{} +> Eine leistungsstarke und flexible Template-Engine für .NET 8.0 mit Unterstützung für einfache String-Templates und komplexe Razor-Templates. - public class TemplateEngine{...} -} -``` - - -The TemplateEngine replaces values from properties of C# classes in template strings. -The C# class with the data holding properties is called the TemplateDataModel class. -The string with the placeholders is called a string template or template string. +--- +## 🚀 Schnellstart -You can bind the value from your C-property to your string template by using `${YourPropertyName}`. -You can set a custom delimiters. Use the `OpeningDelimiter` and `CloseingDelimiter` properties to handle this. +### Installation -Also you can access parameterless public methods of TemplateDataModell classes by using `${MethodName()}` in your template. +```bash +dotnet add package MbSoftLab.TemplateEngine.Core +``` + +### Einfaches Beispiel +```csharp +using MbSoftLab.TemplateEngine.Core; -The default is `${` for the start delimiter and `}` for the end delimiter. +var person = new { FirstName = "Max", LastName = "Mustermann" }; +var engine = new TemplateEngine(person, "Hallo ${FirstName} ${LastName}!"); +string result = engine.CreateStringFromTemplate(); +// Output: "Hallo Max Mustermann!" +``` +### Razor-Template-Beispiel ```csharp - Person person = new Person - { - FirstName = "Jo", - LastName="Doe" - }; - -string template = "${FirstName}, ${LastName}"; +public class Person : TemplateDataModel +{ + public string FirstName { get; set; } + public List Tags { get; set; } +} -TemplateEngine templateEngine = new TemplateEngine(person,template); -string outputString = templateEngine.CreateStringFromTemplate(); +var person = new Person { + FirstName = "Anna", + Tags = new List { "Developer", "Designer" } +}; + +var engine = new RazorTemplateEngine(); +engine.TemplateString = @" +

@Model.FirstName

+
    +@foreach(var tag in Model.Tags) { +
  • @tag
  • +} +
"; -Console.Write(outputString); // Output: Jo, Doe +string html = engine.CreateStringFromTemplate(person); ``` --- -## Install Package +## ✨ Features -**NuGet Package:** -https://www.nuget.org/packages/MbSoftLab.TemplateEngine.Core/ +### Zwei leistungsstarke Engines -```PM -PM> Install-Package MbSoftLab.TemplateEngine.Core -``` +- **TemplateEngine** - Schnell und einfach für String-basierte Templates + - Property-Platzhalter: `${PropertyName}` + - Methoden-Aufrufe: `${MethodName()}` + - Anpassbare Delimiters + - Kultur-spezifische Formatierung + +- **RazorTemplateEngine** - Flexibel für komplexe HTML-Templates + - Volle Razor-Syntax + - Listen und Collections + - Bedingungen und Schleifen + - Verschachtelte Objekte ---- +### Unterstützte Datentypen -## Methods -|Methodname |Description | -|------------------------------------------------------------------------|-----------------------------------------------------------------| -|`string CreateStringFromTemplate([string template])` |*Creates a String from Datamodell and Template* | -|`string CreateStringFromJson(templateEngine, string jsonData)` |*Loads the Templatedata from JSON*. - | -|`void LoadTemplateFromFile(string filename)` |*Loads a Stringtemplate from file*. | -|`TemplateEngine()` |Constructor | -|`TemplateEngine(object templateDataModel, string stringTemplate)` |Constructor | -|`TemplateEngine(object templateDataModel)` |Constructor | -|`TemplateEngine()` |Constructor | -|`TemplateEngine(T templateDataModel, string stringTemplate)` |Constructor | -|`TemplateEngine(T templateDataModel)` |Constructor | +✅ String, Byte, Short, Int, Long, Decimal, Double, DateTime, Boolean +❌ Collections (nur mit RazorTemplateEngine) --- -## Propertys +## 📚 Dokumentation + +**Vollständige Dokumentation verfügbar unter [`/docs`](/docs):** -|Propertyname |Datatype |Description | -|----------------------------------------|------------------|-------------------------------------------------------------------------| -|`OpeningDelimiter` |String |Set the beginning delimiter for propertyreplacement | -|`CloseingDelimiter` |String |Set the ending delimiter for propertyreplacement | -|`TemplateDataModel` |Generic / object |Modell with Properys for Dataholding | -|`TemplateString` |string |Templatestring | -|`NullStringValue` |string |String for NULL-Values | -|`CultureInfo` |CultureInfo |Culture for Double and DateTime values | +| Dokument | Beschreibung | +|----------|--------------| +| [📖 Übersicht](/docs/README.md) | Dokumentations-Einstieg | +| [🏗️ Architektur](/docs/architecture.md) | System-Design und Komponenten | +| [📋 API-Referenz](/docs/api.md) | Vollständige API-Dokumentation | +| [💡 Beispiele](/docs/examples.md) | 16+ praktische Code-Beispiele | +| [👨‍💻 Entwickler-Leitfaden](/docs/development.md) | Contribution Guidelines | +| [📝 CHANGELOG](/CHANGELOG.md) | Versions-Historie | +| [🎉 Release Notes](/RELEASENOTES.md) | Aktuelle Version 1.0.8-preview2 | --- -## Exampels +## 💡 Verwendungsbeispiele -### **Load the template and fill with Data from modell** -```csharp -// Create a modell Class for Data - TemplateDataModel templateDataModel = new TemplateDataModel - { - ProjectName = "Projektname" - }; +### Template aus Datei laden -string template = "${ProjectName}"; +```csharp +var engine = new TemplateEngine(customer); +engine.LoadTemplateFromFile("email-template.txt"); +string email = engine.CreateStringFromTemplate(); +``` -TemplateEngine templateEngine = new TemplateEngine(templateDataModel,template); -string outputString = templateEngine.CreateStringFromTemplate(); +### JSON-Daten verwenden -Console.Write(outputString); // Output: ProjectName -``` -### **Load template from file** ```csharp - TemplateDataModel templateDataModel = new TemplateDataModel - { - ProjectName = "Projektname", - CustomerId = "1234", - ProjectUrl = "https://google.com" - }; - - TemplateEngine templateEngine = new TemplateEngine(templateDataModel); - templateEngine.LoadTemplateFromFile("Html.template.html"); - string outputString = templateEngine.CreateStringFromTemplate(); - - Console.WriteLine(outputString); +string jsonData = "{\"Name\":\"Lisa\",\"Email\":\"lisa@example.com\"}"; +var engine = new TemplateEngine(); +engine.TemplateString = "Kunde: ${Name}, E-Mail: ${Email}"; +string result = engine.CreateStringFromTemplateWithJson(jsonData); ``` +### Custom Delimiters -### **Template and model over PropertyInjection** ```csharp - TemplateDataModel templateDataModel = new TemplateDataModel - { - ProjectName = "Projectname", - CustomerId = "1234", - ProjectUrl = "https://google.com" - }; - - string template = "

${ProjectName}

"; - TemplateEngine templateEngine = new TemplateEngine(); - templateEngine.TemplateDataModel = templateDataModel; - templateEngine.TemplateString = template; - Console.WriteLine(templateEngine.CreateStringFromTemplate()); - +var engine = new TemplateEngine(person, "[[FirstName]] [[LastName]]"); +engine.OpeningDelimiter = "[["; +engine.CloseingDelimiter = "]]"; ``` -### **Template and model over DependencyInjection** +### NULL-Werte behandeln + ```csharp +var engine = new TemplateEngine(customer, "${Email}"); +engine.NullStringValue = "Keine Angabe"; +``` - TemplateDataModel templateDataModel = new TemplateDataModel - { - ProjectName = "Projectname", - CustomerId = "1234", - ProjectUrl = "https://google.com" - }; +Weitere Beispiele und Tutorials finden Sie in der [Beispiele-Dokumentation](/docs/examples.md). - string template = "

${ProjectName}

"; - TemplateEngine templateEngine = new TemplateEngine(templateDataModel,template); - Console.WriteLine(templateEngine.CreateStringFromTemplate()); +--- +## 🔧 Hauptfunktionen -``` -### **TemplateEngine with PropertyInjection and generic type** -```csharp - TemplateDataModel templateDataModel = new TemplateDataModel - { - ProjectName = "Projectname", - CustomerId = null, - ProjectUrl = "https://google.de" - }; - - string template = "

{{ProjectName}}

{{CustomerId}}

"; - TemplateEngine templateEngine = new TemplateEngine() - { - TemplateDataModel = templateDataModel, - TemplateString = template, - OpeningDelimiter = "{{", - CloseingDelimiter = "}}", - NullStringValue = "???" - }; - Console.WriteLine(templateEngine.CreateStringFromTemplate()); +### TemplateEngine + +| Feature | Beschreibung | +|---------|--------------| +| Property-Binding | `${PropertyName}` für einfache Werte | +| Methoden-Aufrufe | `${MethodName()}` für parameterlose Methoden | +| Custom Delimiters | Anpassbare Start-/End-Zeichen | +| NULL-Behandlung | Konfigurierbarer NULL-String | +| Formatierung | Kultur-spezifisch (CultureInfo) | +| JSON-Support | Direkte Deserialisierung | +| File-Loading | Templates aus Dateien laden | + +### RazorTemplateEngine + +| Feature | Beschreibung | +|---------|--------------| +| Razor-Syntax | Volle C#-Unterstützung in Templates | +| Collections | Listen, Arrays, IEnumerable | +| Kontrollstrukturen | `@if`, `@foreach`, `@for`, `@switch` | +| Verschachtelung | Komplexe Objekthierarchien | +| Type-Safety | Generische Typisierung | +--- + +## 📦 NuGet Package + +```bash +# .NET CLI +dotnet add package MbSoftLab.TemplateEngine.Core + +# Package Manager +Install-Package MbSoftLab.TemplateEngine.Core + +# PackageReference + ``` +**NuGet Gallery:** https://www.nuget.org/packages/MbSoftLab.TemplateEngine.Core/ + +--- + +## 🤝 Contributing + +Wir freuen uns über Beiträge! Bitte lesen Sie unseren [Entwickler-Leitfaden](/docs/development.md) für: + +- Entwicklungsumgebung einrichten +- Code-Konventionen +- Branch-Strategie +- Pull Request Prozess --- - ## Datatype compatibility - -- ✔ String -- ✔ Byte -- ✔ Short -- ✔ UShort -- ✔ Long -- ✔ ULong -- ✔ SByte -- ✔ Char -- ✔ UInt16 -- ✔ Int32 -- ✔ UInt64 -- ✔ Int16 -- ✔ Int32 -- ✔ Int64 -- ✔ Decimal -- ✔ Double -- ✔ DateTime -- ✔ Boolean -- ❌ Object -- ❌ CustomClasses -- ❌ IList, List, Dictionary, IEnumerable, etc.. - - +## 📄 Lizenz + +Dieses Projekt ist unter der [MIT-Lizenz](LICENSE) lizenziert. + +Copyright © 2021 MbSoftLab --- - -## Repo -https://github.com/mbsoftlab/MbSoftLab.TemplateEngine.Core +## 🔗 Links + +- **GitHub Repository:** https://github.com/mbsoftlab/MbSoftLab.TemplateEngine.Core +- **Issues/Feedback:** https://github.com/mbsoftlab/MbSoftLab.TemplateEngine.Core/issues +- **NuGet Package:** https://www.nuget.org/packages/MbSoftLab.TemplateEngine.Core/ + --- -## Issues +## 🆕 Version 1.0.8-preview2 + +**Highlights:** +- ✨ RazorTemplateEngine für komplexe HTML-Templates +- ✨ Erweiterte Methoden-Aufrufe in Templates +- 🔧 Verbesserter Build- und Release-Prozess +- 📚 Umfassende deutsche Dokumentation + +Siehe [Release Notes](/RELEASENOTES.md) für Details. + +--- -[report an issue](https://github.com/mbsoftlab/MbSoftLab.TemplateEngine.Core/issues) \ No newline at end of file +

+ Built with ❤️ by MbSoftLab +

diff --git a/RELEASENOTES.md b/RELEASENOTES.md new file mode 100644 index 0000000..51a0d0e --- /dev/null +++ b/RELEASENOTES.md @@ -0,0 +1,138 @@ +# Release Notes + +## Version 1.0.8-preview2 + +**Release-Datum:** In Entwicklung +**Commit-Referenz:** 5c37e68 + +### Übersicht + +Diese Preview-Version erweitert die MbSoftLab.TemplateEngine.Core um Razor-Template-Unterstützung und verbessert den Build- und Veröffentlichungsprozess. + +--- + +## ✨ Neue Features + +### 1. Razor Template Engine +Die neue `RazorTemplateEngine` Klasse ermöglicht die Nutzung von Razor-Syntax für komplexe HTML-Templates: + +```csharp +Person person = new Person { FirstName = "Max", LastName = "Mustermann" }; +var engine = new RazorTemplateEngine(); +engine.LoadTemplateFromFile("template.cshtml"); +string result = engine.CreateStringFromTemplate(person); +``` + +**Vorteile:** +- Volle Razor-Syntax-Unterstützung (Schleifen, Bedingungen, etc.) +- Typsichere Template-Erstellung +- Kompilierte Templates für bessere Performance + +### 2. Erweiterte Template-Funktionalität +- **Methodenaufrufe:** Templates können jetzt parameterlose öffentliche Methoden aufrufen: `${MethodName()}` +- **JSON-Unterstützung:** Direkte Deserialisierung von JSON in TemplateDataModel +- **Template aus Datei laden:** `LoadTemplateFromFile()` Erweiterungsmethode + +### 3. Einheitliches Interface-Design +- `ITemplateEngine` als gemeinsames Interface für beide Engine-Typen +- `ITemplateEngineConfig` für konsistente Konfiguration +- Bessere Erweiterbarkeit und Testbarkeit + +--- + +## 🔧 Verbesserungen + +### Build und Deployment +- **Modernisierter Release-Workflow:** + - Umstellung von veralteter NuGet-Publish-Action auf native dotnet-Befehle + - `dotnet pack` für Package-Erstellung + - `dotnet nuget push` für NuGet-Veröffentlichung + - Verbesserte Zuverlässigkeit und Wartbarkeit + +### Code-Qualität +- XML-Dokumentation für alle öffentlichen APIs +- Einheitliche Fehlerbehandlung +- Kultur-spezifische Formatierung konfigurierbar + +--- + +## 📦 Technische Spezifikationen + +### Framework und Versionen +- **Target Framework:** .NET 8.0 +- **Assembly Version:** 1.0.8.2 +- **Package Version:** 1.0.8-preview2 +- **Lizenz:** MIT + +### Abhängigkeiten +- RazorEngineCore 2020.10.1 + +### Build-Konfiguration +- Automatische Package-Generierung beim Build +- XML-Dokumentationsdatei wird generiert +- NuGet-Package mit Logo und vollständigen Metadaten + +--- + +## 🎯 Anwendungsfälle + +### Simple String-Templates +Ideal für einfache Platzhalter-Ersetzungen in Konfigurationsdateien, E-Mails oder Berichten. + +### Komplexe HTML-Templates +Mit der Razor-Engine können Sie komplexe HTML-Dokumente mit Schleifen, Bedingungen und verschachtelten Strukturen erstellen. + +### Code-Generierung +Nutzen Sie die Template-Engines zur automatischen Code-, Konfigurations- oder Dokumentationsgenerierung. + +--- + +## 📝 Migration von früheren Versionen + +Die API ist abwärtskompatibel. Bestehender Code funktioniert weiterhin: + +```csharp +// Alter Code funktioniert weiterhin +var engine = new TemplateEngine(dataModel, template); +string result = engine.CreateStringFromTemplate(); +``` + +Neue Features können optional genutzt werden: + +```csharp +// Neuer Code mit Razor +var razorEngine = new RazorTemplateEngine(dataModel, razorTemplate); +string result = razorEngine.CreateStringFromTemplate(); +``` + +--- + +## 🐛 Bekannte Einschränkungen + +1. **Collections nicht unterstützt** in der einfachen TemplateEngine + - Workaround: Verwenden Sie RazorTemplateEngine für Listen und Arrays + +2. **Nur parameterlose Methoden** werden unterstützt + - Zukünftige Versionen könnten Methoden mit Parametern unterstützen + +3. **XML-Dokumentations-Warnung** bei `LoadTemplateFromFile` + - Wird in der nächsten Version behoben + +--- + +## 🔗 Links und Ressourcen + +- **NuGet Package:** https://www.nuget.org/packages/MbSoftLab.TemplateEngine.Core/ +- **GitHub Repository:** https://github.com/mbsoftlab/MbSoftLab.TemplateEngine.Core +- **Issues:** https://github.com/mbsoftlab/MbSoftLab.TemplateEngine.Core/issues +- **Dokumentation:** Siehe `/docs` Verzeichnis + +--- + +## 🙏 Danksagung + +Danke an alle Mitwirkenden und Nutzer für ihr Feedback und ihre Unterstützung bei der Weiterentwicklung dieses Projekts. + +--- + +**Commit-Referenz für diese Release Notes:** 5c37e68 diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..ed1cd88 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,237 @@ +# MbSoftLab.TemplateEngine.Core - Dokumentation + +**Version:** 1.0.8-preview2 +**Commit-Referenz:** 5c37e68 +**Dokumentations-Stand:** Dezember 2025 + +--- + +## Willkommen + +Willkommen zur offiziellen Dokumentation der **MbSoftLab.TemplateEngine.Core** Bibliothek - einer leistungsstarken und flexiblen Template-Engine für .NET 8.0. + +Diese Bibliothek bietet zwei verschiedene Ansätze zur Template-Verarbeitung: +- **TemplateEngine** - Schnell und einfach für String-basierte Templates +- **RazorTemplateEngine** - Mächtig und flexibel für komplexe HTML-Templates mit Razor-Syntax + +--- + +## 📚 Dokumentations-Struktur + +### [Architektur](architecture.md) +Detaillierte technische Übersicht der Bibliothek: +- Gesamt-Architektur und Komponenten-Diagramme +- Klassen-Hierarchie und Beziehungen +- Datenfluss und Verarbeitungs-Pipelines +- Design-Entscheidungen und Begründungen +- Erweiterungspunkte für zukünftige Features + +**Für wen:** Entwickler, die die interne Struktur verstehen wollen + +### [API-Dokumentation](api.md) +Vollständige API-Referenz: +- Alle öffentlichen Klassen und Interfaces +- Methoden-Signaturen und Parameter +- Eigenschaften und deren Verwendung +- Template-Syntax für beide Engine-Typen +- Unterstützte Datentypen +- Best Practices und Fehlerbehandlung + +**Für wen:** Entwickler, die die API verwenden + +### [Beispiele und Tutorials](examples.md) +Praktische Codebeispiele: +- Schnellstart-Anleitung +- Einfache bis fortgeschrittene Beispiele +- Razor-Template-Beispiele +- Real-World-Szenarien (E-Mail, Reports, Konfigurationen) +- Tipps und Tricks für effiziente Nutzung + +**Für wen:** Einsteiger und Entwickler, die konkrete Anwendungsfälle suchen + +### [Entwickler-Leitfaden](development.md) +Informationen für Contributors: +- Entwicklungsumgebung einrichten +- Projekt-Struktur und Organisation +- Build, Test und Debugging +- Code-Konventionen und Standards +- Contribution Guidelines +- CI/CD Pipeline-Details + +**Für wen:** Contributors und Maintainer + +--- + +## 🚀 Schnellstart + +### Installation + +```bash +# NuGet Package Manager +Install-Package MbSoftLab.TemplateEngine.Core + +# .NET CLI +dotnet add package MbSoftLab.TemplateEngine.Core +``` + +### Erstes Beispiel + +```csharp +using MbSoftLab.TemplateEngine.Core; + +// Datenmodell +var person = new { FirstName = "Max", LastName = "Mustermann" }; + +// Template +string template = "Hallo ${FirstName} ${LastName}!"; + +// Template-Engine +var engine = new TemplateEngine(person, template); + +// String erstellen +string result = engine.CreateStringFromTemplate(); +// Output: "Hallo Max Mustermann!" +``` + +Mehr Beispiele finden Sie in der [Beispiele-Dokumentation](examples.md). + +--- + +## 📖 Wichtige Dokumente + +### [CHANGELOG.md](/CHANGELOG.md) +Komplette Versions-Historie mit allen Änderungen, neuen Features und Bugfixes. + +### [RELEASENOTES.md](/RELEASENOTES.md) +Detaillierte Release-Informationen für die aktuelle Version mit Migration-Guides und bekannten Einschränkungen. + +### [README.md](/README.md) +Projekt-Übersicht mit grundlegenden Informationen und Links. + +--- + +## 🎯 Häufige Anwendungsfälle + +### 1. Einfache String-Templates +Für Platzhalter-Ersetzungen in Konfigurationen, E-Mails oder einfachen Texten. + +```csharp +var engine = new TemplateEngine(customer, "Hallo ${Name}!"); +``` + +→ Siehe [Einfache Beispiele](/docs/examples/#einfache-beispiele) + +### 2. Komplexe HTML-Templates +Für dynamische HTML-Generierung mit Schleifen, Bedingungen und verschachtelten Objekten. + +```csharp +var engine = new RazorTemplateEngine(); +engine.TemplateString = "@foreach(var item in Model.Items) {
  • @item
  • }"; +``` + +→ Siehe [Razor-Templates](/docs/examples/#razor-templates) + +### 3. Report-Generierung +Für automatisierte Berichte aus Datenmodellen. + +→ Siehe [Praxis-Szenarien](/docs/examples/#praxis-szenarien) + +### 4. Code-Generierung +Für Template-basierte Code- oder Konfigurations-Generierung. + +→ Siehe [Entwickler-Leitfaden](/docs/development/) + +--- + +## 💡 Kernkonzepte + +### Template-Engine (String-basiert) +- **Platzhalter:** `${PropertyName}` oder `${MethodName()}` +- **Custom Delimiters:** Konfigurierbar +- **NULL-Behandlung:** Anpassbarer NULL-String +- **Formatierung:** Kultur-abhängig für Zahlen und Datum +- **Performance:** Sehr schnell für einfache Templates + +### RazorTemplateEngine (Razor-basiert) +- **Razor-Syntax:** Volle C#-Unterstützung +- **Schleifen:** `@foreach`, `@for` +- **Bedingungen:** `@if`, `@switch` +- **Collections:** Listen und Arrays unterstützt +- **Kompilierung:** Templates werden kompiliert für bessere Performance + +--- + +## 🔧 Funktions-Übersicht + +### Unterstützte Datentypen (TemplateEngine) +✅ String, Byte, Short, Int, Long, Decimal, Double, DateTime, Boolean +❌ Collections, Custom Classes (→ Nutzen Sie RazorTemplateEngine) + +### Features +- [x] Property-basierte Platzhalter +- [x] Methoden-Aufrufe (parameterlos) +- [x] Custom Delimiters +- [x] NULL-Wert-Konfiguration +- [x] Kultur-spezifische Formatierung +- [x] JSON-Deserialisierung +- [x] Template aus Datei laden +- [x] Razor-Template-Unterstützung +- [x] Generische Type-Safety +- [x] Interface-basiertes Design +- [x] Konfigurations-Objekt + +--- + +## 📊 Versions-Informationen + +### Aktuelle Version: 1.0.8-preview2 + +**Highlights:** +- Razor-Template-Engine für komplexe HTML-Templates +- Erweiterte Methoden-Aufrufe in Templates +- Verbesserter Build- und Release-Prozess +- Umfassende Dokumentation + +**Breaking Changes:** Keine (abwärtskompatibel) + +Siehe [RELEASENOTES.md](/RELEASENOTES.md) für Details. + +--- + +## 🤝 Contribution + +Wir freuen uns über Beiträge! Bitte lesen Sie den [Entwickler-Leitfaden](/docs/development/#contribution-guidelines) für: +- Branch-Strategie +- Commit-Konventionen +- Pull Request Process +- Code-Standards + +--- + +## 📝 Support und Feedback + +### Issues melden +[GitHub Issues](https://github.com/mbsoftlab/MbSoftLab.TemplateEngine.Core/issues) + +### Fragen stellen +[GitHub Discussions](https://github.com/mbsoftlab/MbSoftLab.TemplateEngine.Core/discussions) + +### Code-Qualität prüfen +[![CodeFactor](https://www.codefactor.io/repository/github/mbsoftlab/mbsoftlab.templateengine.core/badge)](https://www.codefactor.io/repository/github/mbsoftlab/mbsoftlab.templateengine.core) + +--- + +## 📦 Links + +- **NuGet Package:** https://www.nuget.org/packages/MbSoftLab.TemplateEngine.Core/ +- **GitHub Repository:** https://github.com/mbsoftlab/MbSoftLab.TemplateEngine.Core +- **License:** MIT (siehe [LICENSE](/LICENSE)) + +--- + +**Letzte Aktualisierung:** Dezember 2025 +**Commit-Referenz:** 5c37e68 + +--- + +*Diese Dokumentation wurde automatisch generiert und wird kontinuierlich aktualisiert.* diff --git a/docs/api.md b/docs/api.md new file mode 100644 index 0000000..e904a39 --- /dev/null +++ b/docs/api.md @@ -0,0 +1,643 @@ +# API-Dokumentation + +**Commit-Referenz:** 5c37e68 +**Dokumentations-Stand:** Dezember 2025 + +--- + +## Inhaltsverzeichnis + +1. [Übersicht](#übersicht) +2. [TemplateEngine](#templateengine) +3. [RazorTemplateEngine](#razortemplateengine) +4. [Interfaces](#interfaces) +5. [Konfiguration](#konfiguration) +6. [Erweiterungsmethoden](#erweiterungsmethoden) +7. [Datentypen](#datentypen) + +--- + +## Übersicht + +Die MbSoftLab.TemplateEngine.Core Bibliothek bietet zwei Hauptklassen für Template-Verarbeitung: + +- **TemplateEngine / TemplateEngine:** Für einfache String-basierte Templates +- **RazorTemplateEngine:** Für komplexe Razor-basierte Templates + +Beide implementieren das `ITemplateEngine` Interface. + +--- + +## TemplateEngine + +### TemplateEngine (nicht-generisch) + +```csharp +public class TemplateEngine : TemplateEngine, ITemplateEngine +``` + +**Beschreibung:** Vereinfachte Version von `TemplateEngine` mit `object` als TemplateDataModel-Typ. + +#### Konstruktoren + +```csharp +// 1. Mit DataModel und Template +public TemplateEngine(object templateDataModel, string stringTemplate) + +// 2. Nur mit DataModel +public TemplateEngine(object templateDataModel) + +// 3. Parameterlos (Eigenschaften später setzen) +public TemplateEngine() +``` + +#### Beispiel + +```csharp +var person = new { FirstName = "Max", LastName = "Mustermann" }; +var engine = new TemplateEngine(person, "Hallo ${FirstName} ${LastName}!"); +string result = engine.CreateStringFromTemplate(); +// Ergebnis: "Hallo Max Mustermann!" +``` + +--- + +### TemplateEngine (generisch) + +```csharp +public class TemplateEngine : ITemplateEngine +``` + +**Beschreibung:** Generische Template-Engine für typisierte DataModels. + +#### Eigenschaften + +| Eigenschaft | Typ | Standardwert | Beschreibung | +|-------------|-----|--------------|--------------| +| `OpeningDelimiter` | `string` | `"${"` | Anfangs-Delimiter für Platzhalter | +| `CloseingDelimiter` | `string` | `"}"` | End-Delimiter für Platzhalter | +| `TemplateDataModel` | `T` | - | Datenmodell mit Properties/Methoden | +| `TemplateString` | `string` | - | Template-String mit Platzhaltern | +| `NullStringValue` | `string` | `"NULL"` | Ersatzwert für NULL-Properties | +| `CultureInfo` | `CultureInfo` | `en-US` | Kultur für Zahlen-/Datumsformatierung | +| `Config` | `ITemplateEngineConfig` | - | Zentrale Konfiguration | + +#### Konstruktoren + +```csharp +// 1. Mit DataModel und Template +public TemplateEngine(T templateDataModel, string stringTemplate) + +// 2. Nur mit DataModel +public TemplateEngine(T templateDataModel) + +// 3. Parameterlos +public TemplateEngine() +``` + +#### Methoden + +##### CreateStringFromTemplate() + +```csharp +public string CreateStringFromTemplate() +``` + +**Beschreibung:** Erstellt String aus aktuellem TemplateString und TemplateDataModel. + +**Rückgabe:** Verarbeiteter String mit ersetzten Platzhaltern. + +**Beispiel:** +```csharp +var engine = new TemplateEngine(); +engine.TemplateDataModel = person; +engine.TemplateString = "Hallo ${FirstName}!"; +string result = engine.CreateStringFromTemplate(); +``` + +--- + +##### CreateStringFromTemplate(string stringTemplate) + +```csharp +public string CreateStringFromTemplate(string stringTemplate = null) +``` + +**Parameter:** +- `stringTemplate` - Optionaler Template-String (überschreibt `TemplateString`) + +**Rückgabe:** Verarbeiteter String. + +**Beispiel:** +```csharp +var engine = new TemplateEngine(person); +string result = engine.CreateStringFromTemplate("${FirstName} ${LastName}"); +``` + +--- + +##### CreateStringFromTemplate(T templateDataModel) + +```csharp +public string CreateStringFromTemplate(T templateDataModel) +``` + +**Parameter:** +- `templateDataModel` - Neues DataModel (überschreibt `TemplateDataModel`) + +**Rückgabe:** Verarbeiteter String. + +**Beispiel:** +```csharp +var engine = new TemplateEngine(); +engine.TemplateString = "Hallo ${FirstName}!"; +string result = engine.CreateStringFromTemplate(person); +``` + +--- + +##### CreateStringFromTemplate(T templateDataModel, string stringTemplate) + +```csharp +public string CreateStringFromTemplate(T templateDataModel, string stringTemplate) +``` + +**Parameter:** +- `templateDataModel` - Neues DataModel +- `stringTemplate` - Neuer Template-String + +**Rückgabe:** Verarbeiteter String. + +**Beispiel:** +```csharp +var engine = new TemplateEngine(); +string result = engine.CreateStringFromTemplate(person, "Hallo ${FirstName}!"); +``` + +--- + +### Template-Syntax + +#### Property-Platzhalter + +```csharp +// DataModel +public class Person { + public string FirstName { get; set; } + public int Age { get; set; } +} + +// Template +"Name: ${FirstName}, Alter: ${Age}" +``` + +#### Methoden-Platzhalter + +```csharp +// DataModel +public class Person { + public string GetFullName() { + return $"{FirstName} {LastName}"; + } +} + +// Template +"Vollständiger Name: ${GetFullName()}" +``` + +**Wichtig:** Nur parameterlose öffentliche Methoden werden unterstützt! + +#### Custom Delimiters + +```csharp +var engine = new TemplateEngine(person, "[[FirstName]] [[LastName]]"); +engine.OpeningDelimiter = "[["; +engine.CloseingDelimiter = "]]"; +string result = engine.CreateStringFromTemplate(); +``` + +--- + +## RazorTemplateEngine + +### RazorTemplateEngine + +```csharp +public class RazorTemplateEngine : ITemplateEngine + where T : TemplateDataModel +``` + +**Beschreibung:** Template-Engine für Razor-Syntax (.cshtml). + +**Einschränkung:** Benötigt `TemplateDataModel` als Basis-Klasse für DataModel. + +#### Konstruktoren + +```csharp +// 1. Mit IRazorEngine (für Dependency Injection) +public RazorTemplateEngine(IRazorEngine razorEngine) + +// 2. Parameterlos (erstellt eigene RazorEngine-Instanz) +public RazorTemplateEngine() + +// 3. Mit DataModel und Template +public RazorTemplateEngine(T dataModel, string templateString) +``` + +#### Eigenschaften + +| Eigenschaft | Typ | Beschreibung | +|-------------|-----|--------------| +| `TemplateDataModel` | `T` | Datenmodell (muss von `TemplateDataModel` erben) | +| `TemplateString` | `string` | Razor-Template (.cshtml Syntax) | +| `Config` | `ITemplateEngineConfig` | Konfiguration | + +**Hinweis:** `OpeningDelimiter`, `CloseingDelimiter`, `NullStringValue` und `CultureInfo` werden ignoriert (Razor hat eigene Syntax). + +#### Methoden + +##### CreateStringFromTemplate() + +```csharp +public string CreateStringFromTemplate(string csHtmlTemplate = null) +``` + +**Parameter:** +- `csHtmlTemplate` - Optionales Razor-Template (überschreibt `TemplateString`) + +**Rückgabe:** Gerendeter HTML-String. + +**Beispiel:** +```csharp +var engine = new RazorTemplateEngine(); +engine.TemplateString = "@Model.FirstName @Model.LastName"; +string result = engine.CreateStringFromTemplate(person); +``` + +--- + +##### CreateStringFromTemplate(T templateDataModel) + +```csharp +public string CreateStringFromTemplate(T templateDataModel) +``` + +**Parameter:** +- `templateDataModel` - Neues DataModel + +**Rückgabe:** Gerendeter HTML-String. + +--- + +##### CreateStringFromTemplate(T templateDataModel, string csHtmlTemplate) + +```csharp +public string CreateStringFromTemplate(T templateDataModel, string csHtmlTemplate) +``` + +**Parameter:** +- `templateDataModel` - Neues DataModel +- `csHtmlTemplate` - Neues Razor-Template + +**Rückgabe:** Gerendeter HTML-String. + +--- + +### Razor-Template-Syntax + +```cshtml +@* Person-Daten anzeigen *@ +

    @Model.FirstName @Model.LastName

    + +@* Bedingte Anzeige *@ +@if (Model.Age >= 18) { +

    Volljährig

    +} else { +

    Minderjährig

    +} + +@* Listen iterieren *@ +
      +@foreach(var tag in Model.Tags) { +
    • @tag
    • +} +
    + +@* Verschachtelte Objekte *@ +

    Adresse: @Model.Address.Street, @Model.Address.PostCode

    +``` + +--- + +## Interfaces + +### ITemplateEngine + +```csharp +public interface ITemplateEngine +{ + string CloseingDelimiter { get; set; } + ITemplateEngineConfig Config { get; set; } + CultureInfo CultureInfo { get; set; } + string NullStringValue { get; set; } + string OpeningDelimiter { get; set; } + T TemplateDataModel { get; set; } + string TemplateString { get; set; } + + string CreateStringFromTemplate(string stringTemplate = null); + string CreateStringFromTemplate(T templateDataModel); + string CreateStringFromTemplate(T templateDataModel, string stringTemplate); +} +``` + +**Beschreibung:** Gemeinsames Interface für beide Template-Engine-Typen. + +**Verwendung:** Ermöglicht austauschbare Nutzung von TemplateEngine und RazorTemplateEngine. + +**Beispiel:** +```csharp +public void ProcessTemplate(ITemplateEngine engine, Person person) { + string result = engine.CreateStringFromTemplate(person); + // Funktioniert mit beiden Engine-Typen +} +``` + +--- + +### ITemplateEngineConfig + +```csharp +public interface ITemplateEngineConfig +{ + string OpeningDelimiter { get; set; } + string CloseingDelimiter { get; set; } + string TemplateString { get; set; } + T TemplateDataModel { get; set; } + string NullStringValue { get; set; } + CultureInfo CultureInfo { get; set; } +} +``` + +**Beschreibung:** Interface für Template-Engine-Konfiguration. + +--- + +## Konfiguration + +### TemplateEngineConfig + +```csharp +public class TemplateEngineConfig : ITemplateEngineConfig +``` + +**Beschreibung:** Konfigurationsklasse für zentrale Engine-Einstellungen. + +#### Beispiel + +```csharp +var config = new TemplateEngineConfig { + OpeningDelimiter = "{{", + CloseingDelimiter = "}}", + TemplateString = "Hallo {{FirstName}}!", + TemplateDataModel = person, + NullStringValue = "???", + CultureInfo = CultureInfo.GetCultureInfo("de-DE") +}; + +var engine = new TemplateEngine(); +engine.Config = config; + +string result = engine.CreateStringFromTemplate(); +``` + +**Vorteile:** +- Zentrale Konfiguration +- Wiederverwendbar +- Testfreundlich + +--- + +## Erweiterungsmethoden + +### TemplateEngineExtensions + +```csharp +public static class TemplateEngineExtensions +``` + +#### CreateStringFromTemplateWithJson + +```csharp +public static string CreateStringFromTemplateWithJson( + this ITemplateEngine templateEngine, + string jsonData) +``` + +**Beschreibung:** Deserialisiert JSON zu DataModel und erstellt String. + +**Parameter:** +- `jsonData` - JSON-String mit Daten + +**Rückgabe:** Verarbeiteter String. + +**Beispiel:** +```csharp +string json = "{\"FirstName\":\"Max\",\"LastName\":\"Mustermann\"}"; +var engine = new TemplateEngine(); +engine.TemplateString = "Hallo ${FirstName}!"; +string result = engine.CreateStringFromTemplateWithJson(json); +// Ergebnis: "Hallo Max!" +``` + +--- + +#### LoadTemplateFromFile + +```csharp +public static void LoadTemplateFromFile( + this ITemplateEngine templateEngine, + string path) +``` + +**Beschreibung:** Lädt Template-String aus Datei. + +**Parameter:** +- `path` - Dateipfad zum Template + +**Beispiel:** +```csharp +var engine = new TemplateEngine(person); +engine.LoadTemplateFromFile("templates/greeting.txt"); +string result = engine.CreateStringFromTemplate(); +``` + +**Template-Datei (greeting.txt):** +``` +Hallo ${FirstName} ${LastName}! +Ihr Alter: ${Age} +``` + +--- + +## Datentypen + +### Unterstützte Typen (TemplateEngine) + +Die `TemplateEngine` Klasse unterstützt folgende Datentypen für Properties: + +#### Primitive Typen +- `string` +- `byte` +- `sbyte` +- `char` +- `short` (Int16) +- `ushort` (UInt16) +- `int` (Int32) +- `uint` (UInt32) +- `long` (Int64) +- `ulong` (UInt64) + +#### Numerische Typen +- `decimal` +- `double` + +#### Weitere Typen +- `DateTime` +- `bool` (Boolean) + +#### Nicht unterstützte Typen +- **Object** (generisches object) +- **Custom Classes** (eigene Klassen) +- **Collections** (List, Array, Dictionary, IEnumerable, etc.) + +**Workaround für Collections:** Verwenden Sie `RazorTemplateEngine` für komplexe Datenstrukturen. + +--- + +### TemplateDataModel + +```csharp +public class TemplateDataModel : RazorEngineTemplateBase +{ + [JsonIgnore] + public new T Model { get; set; } + + public string GetNullstringValue() +} +``` + +**Beschreibung:** Basis-Klasse für DataModels in `RazorTemplateEngine`. + +**Verwendung:** +```csharp +public class Person : TemplateDataModel { + public string FirstName { get; set; } + public string LastName { get; set; } + public int Age { get; set; } + public List Tags { get; set; } +} +``` + +**Wichtig:** Nur für `RazorTemplateEngine` erforderlich, nicht für `TemplateEngine`. + +--- + +## Kulturabhängige Formatierung + +### CultureInfo-Verwendung + +```csharp +var person = new Person { + Salary = 1234.56, + BirthDate = new DateTime(1990, 5, 15) +}; + +// Deutsche Formatierung +var engineDE = new TemplateEngine(person, "Gehalt: ${Salary}, Geburt: ${BirthDate}"); +engineDE.CultureInfo = CultureInfo.GetCultureInfo("de-DE"); +string resultDE = engineDE.CreateStringFromTemplate(); +// Ergebnis: "Gehalt: 1234,56, Geburt: 15.05.1990 00:00:00" + +// US-Formatierung +var engineUS = new TemplateEngine(person, "Salary: ${Salary}, Birth: ${BirthDate}"); +engineUS.CultureInfo = CultureInfo.GetCultureInfo("en-US"); +string resultUS = engineUS.CreateStringFromTemplate(); +// Ergebnis: "Salary: 1234.56, Birth: 5/15/1990 12:00:00 AM" +``` + +--- + +## Fehlerbehandlung + +### NotSupportedException + +Wird geworfen, wenn ein nicht unterstützter Datentyp verwendet wird: + +```csharp +public class Person { + public string Name { get; set; } + public List Tags { get; set; } // Nicht unterstützt! +} + +var engine = new TemplateEngine(person, "${Tags}"); +// Wirft: NotSupportedException: Type 'System.Collections.Generic.List`1[System.String]' not supported +``` + +**Lösung:** Verwenden Sie `RazorTemplateEngine` für Collections. + +--- + +## Best Practices + +### 1. Typsichere Nutzung mit Generics + +```csharp +// ✅ Gut: Typsicher +var engine = new TemplateEngine(person, template); + +// ❌ Vermeiden: Untypisiert +var engine = new TemplateEngine(person, template); +``` + +### 2. Config-Objekt für Wiederverwendung + +```csharp +// ✅ Gut: Wiederverwendbare Konfiguration +var config = new TemplateEngineConfig { + OpeningDelimiter = "{{", + CloseingDelimiter = "}}", + NullStringValue = "N/A" +}; + +var engine1 = new TemplateEngine { Config = config }; +var engine2 = new TemplateEngine { Config = config }; +``` + +### 3. Erweiterungsmethoden nutzen + +```csharp +// ✅ Gut: Fluent API +var engine = new TemplateEngine(); +engine.LoadTemplateFromFile("template.txt"); +string result = engine.CreateStringFromTemplate(person); + +// ❌ Vermeiden: Manuelles File-Handling +string template = File.ReadAllText("template.txt"); +var engine = new TemplateEngine(person, template); +``` + +### 4. RazorTemplateEngine für komplexe Szenarien + +```csharp +// ✅ Gut: RazorTemplateEngine für Listen +var engine = new RazorTemplateEngine(); +engine.TemplateString = "@foreach(var tag in Model.Tags) {
  • @tag
  • }"; + +// ❌ Nicht möglich: TemplateEngine unterstützt keine Collections +var engine = new TemplateEngine(person, "${Tags}"); // Fehler! +``` + +--- + +**Letzte Aktualisierung:** Dezember 2025 +**Commit-Referenz:** 5c37e68 diff --git a/docs/architecture.md b/docs/architecture.md new file mode 100644 index 0000000..7103f46 --- /dev/null +++ b/docs/architecture.md @@ -0,0 +1,378 @@ +# Architektur-Übersicht + +**Commit-Referenz:** 5c37e68 +**Dokumentations-Stand:** Dezember 2025 + +--- + +## Inhaltsverzeichnis + +1. [Überblick](#überblick) +2. [Architektur-Diagramme](#architektur-diagramme) +3. [Komponenten](#komponenten) +4. [Datenfluss](#datenfluss) +5. [Design-Entscheidungen](#design-entscheidungen) + +--- + +## Überblick + +MbSoftLab.TemplateEngine.Core ist eine .NET 8.0 Bibliothek, die zwei verschiedene Template-Engine-Implementierungen bereitstellt: + +1. **TemplateEngine** - Einfacher, schneller String-basierter Template-Engine +2. **RazorTemplateEngine** - Komplexer Razor-basierter Template-Engine für HTML + +Beide implementieren das gemeinsame `ITemplateEngine` Interface. + +--- + +## Architektur-Diagramme + +### Gesamt-Architektur + +```mermaid +graph TB + subgraph "Client Code" + A[Benutzer-Anwendung] + end + + subgraph "MbSoftLab.TemplateEngine.Core" + B[ITemplateEngine<T>] + C[TemplateEngine<T>] + D[RazorTemplateEngine<T>] + E[TemplateDataModelProcessor] + F[PlaceholderValueReplacer] + G[ReplacementActionCollection] + H[ITemplateEngineConfig<T>] + I[TemplateEngineConfig<T>] + J[TemplateEngineExtensions] + end + + subgraph "External Dependencies" + K[RazorEngineCore] + end + + A --> B + B --> C + B --> D + C --> E + C --> H + D --> H + D --> K + E --> F + F --> G + H --> I + A --> J + J --> B +``` + +### Klassen-Hierarchie + +```mermaid +classDiagram + class ITemplateEngine~T~ { + <> + +string OpeningDelimiter + +string CloseingDelimiter + +string NullStringValue + +T TemplateDataModel + +string TemplateString + +CultureInfo CultureInfo + +ITemplateEngineConfig~T~ Config + +CreateStringFromTemplate() string + +CreateStringFromTemplate(T) string + +CreateStringFromTemplate(T, string) string + } + + class TemplateEngine~T~ { + -string _outputString + -string _openingDelimiter + -string _closeingDelimiter + -T _templateDataModel + -string _templateString + -string _nullStringValue + +CreateStringFromTemplate() string + } + + class RazorTemplateEngine~T~ { + -IRazorEngine razorEngine + +CreateStringFromTemplate() string + } + + class ITemplateEngineConfig~T~ { + <> + +string OpeningDelimiter + +string CloseingDelimiter + +string TemplateString + +T TemplateDataModel + +string NullStringValue + +CultureInfo CultureInfo + } + + class TemplateEngineConfig~T~ { + -string _openingDelimiter + -string _closeingDelimiter + -string _templateString + -T _templateDataModel + -string _nullStringValue + } + + class TemplateDataModel~T~ { + +T Model + +GetNullstringValue() string + } + + ITemplateEngine~T~ <|.. TemplateEngine~T~ + ITemplateEngine~T~ <|.. RazorTemplateEngine~T~ + ITemplateEngineConfig~T~ <|.. TemplateEngineConfig~T~ + RazorEngineTemplateBase <|-- TemplateDataModel~T~ + TemplateEngine~T~ --> ITemplateEngineConfig~T~ + RazorTemplateEngine~T~ --> ITemplateEngineConfig~T~ + RazorTemplateEngine~T~ --> TemplateDataModel~T~ +``` + +### Template-Verarbeitungs-Pipeline (TemplateEngine) + +```mermaid +sequenceDiagram + participant Client + participant TemplateEngine + participant Processor as TemplateDataModelProcessor + participant Replacer as PlaceholderValueReplacer + participant Actions as ReplacementActionCollection + + Client->>TemplateEngine: CreateStringFromTemplate() + TemplateEngine->>TemplateEngine: Validiere Eingaben + TemplateEngine->>Replacer: new PlaceholderValueReplacer(template, nullValue) + TemplateEngine->>Processor: new TemplateDataModelProcessor(delimiters, replacer) + TemplateEngine->>Processor: ProcessTemplateDataModell(dataModel) + + Processor->>Processor: ProcessTemplateDataModelClassMethods() + Processor->>Processor: Iteriere über Methoden + loop Für jede öffentliche parameterlose Methode + Processor->>Processor: Rufe Methode auf + Processor->>Replacer: ReplacePlaceholderWithValue(type, name, value) + Replacer->>Actions: InvokeReplacementActionForType(type, name, value) + Actions->>Replacer: Führe Ersetzung aus + end + + Processor->>Processor: ProcessTemplateDataModelClassPropertys() + loop Für jede lesbare Property + Processor->>Processor: Lese Property-Wert + Processor->>Replacer: ReplacePlaceholderWithValue(type, name, value) + Replacer->>Actions: InvokeReplacementActionForType(type, name, value) + Actions->>Replacer: Führe Ersetzung aus + end + + Processor-->>TemplateEngine: Verarbeitung abgeschlossen + TemplateEngine->>Replacer: Hole OutputString + Replacer-->>TemplateEngine: Ausgabe-String + TemplateEngine-->>Client: Fertiger String +``` + +### Template-Verarbeitungs-Pipeline (RazorTemplateEngine) + +```mermaid +sequenceDiagram + participant Client + participant RazorEngine as RazorTemplateEngine + participant RazorCore as RazorEngineCore + participant Template as Compiled Template + + Client->>RazorEngine: CreateStringFromTemplate() + RazorEngine->>RazorEngine: Validiere Eingaben + RazorEngine->>RazorCore: Compile(templateString) + RazorCore->>RazorCore: Parse Razor-Syntax + RazorCore->>RazorCore: Kompiliere zu C#-Code + RazorCore-->>RazorEngine: IRazorEngineCompiledTemplate + RazorEngine->>Template: Run(templateDataModel) + Template->>Template: Führe kompilierten Code aus + Template->>Template: Zugriff auf Model-Properties + Template-->>RazorEngine: Ausgabe-String + RazorEngine-->>Client: Fertiger String +``` + +--- + +## Komponenten + +### 1. Template Engines + +#### TemplateEngine +- **Zweck:** Schnelle, einfache String-Template-Verarbeitung +- **Strategie:** Reflection-basierte Platzhalter-Ersetzung +- **Performance:** Sehr gut für einfache Templates +- **Einschränkungen:** Keine Collections, keine komplexe Logik + +#### RazorTemplateEngine +- **Zweck:** Komplexe HTML-Template-Generierung +- **Strategie:** Razor-Syntax-Kompilierung +- **Performance:** Gut für komplexe Templates (Kompilierung beim ersten Mal) +- **Vorteile:** Volle C#-Syntax, Schleifen, Bedingungen, etc. + +### 2. Datenverarbeitung + +#### TemplateDataModelProcessor +- **Verantwortung:** Verarbeitet TemplateDataModel-Klassen +- **Funktionen:** + - Extrahiert Properties via Reflection + - Extrahiert parameterlose öffentliche Methoden + - Filtert Basis-Klassen-Methoden (Blacklist) + - Delegiert Wert-Ersetzung an PlaceholderValueReplacer + +#### PlaceholderValueReplacer +- **Verantwortung:** Ersetzt Platzhalter durch Werte +- **Funktionen:** + - Verwaltet Output-String + - Delegiert typ-spezifische Ersetzung an ReplacementActionCollection + - Handhabt NULL-Werte + - Wendet CultureInfo für Formatierung an + +#### ReplacementActionCollection +- **Verantwortung:** Typ-spezifische Ersetzungslogik +- **Funktionen:** + - Registriert Actions für jeden unterstützten Typ + - Wirft NotSupportedException für nicht unterstützte Typen + - Ermöglicht Erweiterung durch neue Typen + +### 3. Konfiguration + +#### ITemplateEngineConfig / TemplateEngineConfig +- **Zweck:** Zentrale Konfiguration für Template-Engines +- **Einstellungen:** + - Delimiter (OpeningDelimiter, CloseingDelimiter) + - NULL-Wert-String + - CultureInfo für Formatierung + - TemplateDataModel und TemplateString + +### 4. Erweiterungen + +#### TemplateEngineExtensions +- **CreateStringFromTemplateWithJson:** JSON-Deserialisierung + Template-Verarbeitung +- **LoadTemplateFromFile:** Lädt Template-String aus Datei + +--- + +## Datenfluss + +### Einfacher TemplateEngine-Ablauf + +``` +1. Client erstellt TemplateEngine mit DataModel und Template +2. Client ruft CreateStringFromTemplate() auf +3. TemplateEngine erstellt PlaceholderValueReplacer +4. TemplateEngine erstellt TemplateDataModelProcessor +5. Processor verarbeitet Methoden: + - Findet öffentliche parameterlose Methoden + - Ruft jede Methode auf + - Übergibt Ergebnis an Replacer +6. Processor verarbeitet Properties: + - Iteriert über alle lesbaren Properties + - Liest jeden Wert + - Übergibt an Replacer +7. Replacer ersetzt jeden Platzhalter: + - Prüft Typ + - Ruft passende ReplacementAction auf + - Ersetzt im Output-String +8. TemplateEngine gibt fertigen String zurück +``` + +### RazorTemplateEngine-Ablauf + +``` +1. Client erstellt RazorTemplateEngine mit DataModel und Razor-Template +2. Client ruft CreateStringFromTemplate() auf +3. RazorTemplateEngine kompiliert Template (falls nicht gecacht) +4. Kompiliertes Template wird mit DataModel ausgeführt +5. Razor-Code greift direkt auf Model-Properties zu +6. Ausgabe-String wird generiert und zurückgegeben +``` + +--- + +## Design-Entscheidungen + +### 1. Zwei Template-Engine-Typen + +**Entscheidung:** Bereitstellung von zwei verschiedenen Engines statt nur einer. + +**Begründung:** +- Einfache Templates benötigen keine Razor-Kompilierung (Performance) +- Komplexe Templates profitieren von Razor-Syntax (Flexibilität) +- Gemeinsames Interface ermöglicht austauschbare Nutzung + +**Trade-off:** Mehr Code-Wartung, aber bessere Use-Case-Abdeckung + +### 2. Reflection-basierte Property-Verarbeitung + +**Entscheidung:** Verwendung von Reflection zur Laufzeit für Property-Zugriff. + +**Begründung:** +- Keine Code-Generierung notwendig +- Funktioniert mit allen Typen ohne zusätzliche Konfiguration +- Einfache API + +**Trade-off:** Geringere Performance als kompilierte Zugriffe, aber akzeptabel für Use-Case + +### 3. Typ-spezifische Ersetzungs-Actions + +**Entscheidung:** Dictionary mit Actions pro Typ statt generischer Konvertierung. + +**Begründung:** +- Präzise Kontrolle über Formatierung pro Typ +- Erweiterbar für neue Typen +- Klare Fehlermeldungen bei nicht unterstützten Typen + +**Trade-off:** Mehr initialer Code, aber flexibler und wartbarer + +### 4. Immutable Delimiter nach Trim + +**Entscheidung:** Delimiter werden getrimmt beim Setzen. + +**Begründung:** +- Verhindert Whitespace-Fehler in Templates +- User-freundlicher +- Konsistentes Verhalten + +**Trade-off:** Keine exakte Whitespace-Kontrolle möglich (sehr selten benötigt) + +### 5. Blacklist für Methoden + +**Entscheidung:** Blacklist-basierte Filterung von Basis-Methoden. + +**Begründung:** +- Verhindert ungewollte Methoden-Aufrufe (ToString, GetHashCode, etc.) +- Einfach erweiterbar +- Schutz vor unerwünschtem Verhalten + +**Trade-off:** Muss bei neuen Basis-Klassen erweitert werden + +### 6. .NET 8.0 als Target Framework + +**Entscheidung:** Ausschließlich .NET 8.0, keine Multi-Targeting. + +**Begründung:** +- Modernste .NET-Features verfügbar +- Bessere Performance +- Einfachere Wartung (nur ein Target) + +**Trade-off:** Nicht mit älteren .NET-Versionen kompatibel + +--- + +## Erweiterungspunkte + +### Zukünftige Erweiterungsmöglichkeiten + +1. **Template-Caching:** Kompilierte Razor-Templates cachen für bessere Performance +2. **Async-Support:** Asynchrone Template-Verarbeitung +3. **Collection-Support in TemplateEngine:** Iteration über Listen direkt im Template +4. **Methoden mit Parametern:** Unterstützung für Methoden-Aufrufe mit Argumenten +5. **Custom Type Formatters:** Benutzer-definierte Formatierung für eigene Typen +6. **Template-Vererbung:** Include/Import von Templates +7. **Partial Templates:** Wiederverwendbare Template-Fragmente + +--- + +**Letzte Aktualisierung:** Dezember 2025 +**Commit-Referenz:** 5c37e68 diff --git a/docs/development.md b/docs/development.md new file mode 100644 index 0000000..529f41c --- /dev/null +++ b/docs/development.md @@ -0,0 +1,627 @@ +# Entwickler-Leitfaden + +**Commit-Referenz:** 5c37e68 +**Dokumentations-Stand:** Dezember 2025 + +--- + +## Inhaltsverzeichnis + +1. [Entwicklungsumgebung einrichten](#entwicklungsumgebung-einrichten) +2. [Projekt-Struktur](#projekt-struktur) +3. [Build und Tests](#build-und-tests) +4. [Code-Konventionen](#code-konventionen) +5. [Contribution Guidelines](#contribution-guidelines) +6. [CI/CD Pipeline](#cicd-pipeline) +7. [Versionierung](#versionierung) +8. [Debugging-Tipps](#debugging-tipps) + +--- + +## Entwicklungsumgebung einrichten + +### Voraussetzungen + +- **.NET 8.0 SDK** oder höher +- **IDE:** Visual Studio 2022, Visual Studio Code, oder JetBrains Rider +- **Git** für Versionskontrolle + +### Installation + +```bash +# Repository klonen +git clone https://github.com/mbsoftlab/MbSoftLab.TemplateEngine.Core.git +cd MbSoftLab.TemplateEngine.Core + +# Dependencies wiederherstellen +dotnet restore + +# Projekt bauen +dotnet build + +# Tests ausführen +dotnet test +``` + +### Empfohlene VS Code Extensions + +- C# Dev Kit +- .NET Extension Pack +- NuGet Package Manager +- EditorConfig for VS Code + +### Empfohlene Visual Studio Workloads + +- .NET Desktop-Entwicklung +- ASP.NET- und Webentwicklung + +--- + +## Projekt-Struktur + +``` +MbSoftLab.TemplateEngine.Core/ +├── .github/ +│ └── workflows/ # GitHub Actions CI/CD +│ ├── BuildFromDevelop.yml +│ ├── BuildFromMaster.yml +│ └── Release.yml +├── MbSoftLab.TemplateEngine.Core/ # Haupt-Bibliothek +│ ├── ITemplateEngine.cs # Interface für Template-Engines +│ ├── TemplateEngine.cs # Simple Template-Engine +│ ├── RazorTemplateEngine.cs # Razor-basierte Engine +│ ├── TemplateDataModel.cs # Basis-Klasse für Razor-Models +│ ├── TemplateDataModelProcessor.cs # Property/Methoden-Verarbeitung +│ ├── PlaceholderValueRaplacer.cs # Platzhalter-Ersetzung +│ ├── ReplacementActionCollection.cs # Typ-spezifische Actions +│ ├── ITemplateEngineConfig.cs # Konfigurations-Interface +│ ├── TemplateEngineConfig.cs # Konfigurations-Implementierung +│ ├── TemplateEngineExtensions.cs # Erweiterungsmethoden +│ └── MbSoftLab.TemplateEngine.Core.csproj # Projekt-Datei +├── MbSoftLab.TemplateEngine.Core.Tests/ # Unit-Tests +│ ├── TemplateEngineUnitTest.cs +│ ├── RazorTemplateEngineUnitTest.cs +│ ├── TemplateDataModelDummy.cs # Test-Fixtures +│ └── *.cs # Weitere Test-Dateien +├── MbSoftlab.TemplateEngine.Core.Demo/ # Demo-Anwendung +│ ├── Program.cs +│ ├── Person.cs +│ ├── Address.cs +│ ├── Order.cs +│ └── TestModel.cshtml # Razor-Template-Beispiel +├── docs/ # Dokumentation +│ ├── architecture/ +│ ├── api/ +│ ├── examples/ +│ └── development/ +├── CHANGELOG.md # Versions-Historie +├── RELEASENOTES.md # Release-Informationen +├── README.md # Haupt-Dokumentation +└── MbSoftLab.TemplateEngine.Core.sln # Solution-Datei +``` + +--- + +## Build und Tests + +### Lokaler Build + +```bash +# Debug-Build +dotnet build + +# Release-Build +dotnet build --configuration Release + +# NuGet-Package erstellen +dotnet pack --configuration Release +``` + +**Output:** Das NuGet-Package wird in `bin/Release/` erstellt. + +### Tests ausführen + +```bash +# Alle Tests +dotnet test + +# Mit Verbose-Output +dotnet test --verbosity detailed + +# Nur spezifische Tests +dotnet test --filter "FullyQualifiedName~TemplateEngineUnitTest" + +# Code Coverage (optional) +dotnet test /p:CollectCoverage=true /p:CoverletOutputFormat=opencover +``` + +### Demo-Anwendung ausführen + +```bash +cd MbSoftlab.TemplateEngine.Core.Demo +dotnet run +``` + +Die Demo-Anwendung zeigt ein Razor-Template-Beispiel und öffnet das Ergebnis im Browser. + +--- + +## Code-Konventionen + +### Namenskonventionen + +- **Klassen:** PascalCase (`TemplateEngine`, `PlaceholderValueRaplacer`) +- **Interfaces:** PascalCase mit `I`-Prefix (`ITemplateEngine`) +- **Properties:** PascalCase (`OpeningDelimiter`) +- **Private Felder:** camelCase mit `_`-Prefix (`_outputString`) +- **Methoden:** PascalCase (`CreateStringFromTemplate`) +- **Parameter:** camelCase (`templateDataModel`) + +### Code-Stil + +```csharp +// ✅ Gut +public class TemplateEngine +{ + private string _templateString; + + public string TemplateString + { + get => _templateString; + set => _templateString = value; + } + + public string CreateStringFromTemplate() + { + // Implementation + } +} + +// ❌ Vermeiden +public class templateEngine +{ + public string templatestring; + + public string create_string() { } +} +``` + +### XML-Dokumentation + +Alle öffentlichen APIs müssen XML-Dokumentation haben: + +```csharp +/// +/// Ersetzt alle Properties von templateDataModel im stringTemplate. +/// Die Property-Namen müssen mit den Platzhaltern übereinstimmen. +/// +/// Datenmodell mit Properties +/// Template mit Platzhaltern +/// Verarbeiteter String mit ersetzten Platzhaltern +public string CreateStringFromTemplate(T templateDataModel, string stringTemplate) +{ + // Implementation +} +``` + +### EditorConfig + +Das Projekt verwendet `.editorconfig` für konsistente Code-Formatierung: + +```ini +[*.cs] +indent_style = space +indent_size = 4 +end_of_line = crlf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true +``` + +--- + +## Contribution Guidelines + +### Branch-Strategie + +- **master:** Produktions-Code (stabil) +- **develop:** Entwicklungs-Branch (neueste Features) +- **feature/\*:** Feature-Branches (von develop abzweigen) +- **bugfix/\*:** Bugfix-Branches +- **hotfix/\*:** Dringende Fixes für master + +### Workflow + +1. **Fork erstellen** oder auf **develop** Branch wechseln + ```bash + git checkout develop + git pull origin develop + ``` + +2. **Feature-Branch erstellen** + ```bash + git checkout -b feature/mein-neues-feature + ``` + +3. **Änderungen implementieren** + - Code schreiben + - Tests hinzufügen + - Dokumentation aktualisieren + +4. **Tests ausführen** + ```bash + dotnet test + ``` + +5. **Commit** + ```bash + git add . + git commit -m "feat: Beschreibung des Features" + ``` + +6. **Push und Pull Request** + ```bash + git push origin feature/mein-neues-feature + ``` + Dann Pull Request auf GitHub erstellen. + +### Commit-Message-Konventionen + +Folgen Sie [Conventional Commits](https://www.conventionalcommits.org/): + +``` +feat: Neue Funktion hinzufügen +fix: Bug beheben +docs: Dokumentation aktualisieren +style: Code-Formatierung (keine funktionale Änderung) +refactor: Code-Refactoring +test: Tests hinzufügen oder ändern +chore: Build-Prozess oder Tools ändern +``` + +**Beispiele:** +``` +feat: RazorTemplateEngine für HTML-Templates hinzufügen +fix: NULL-Wert-Behandlung in PlaceholderValueRaplacer korrigieren +docs: API-Dokumentation für CreateStringFromTemplate erweitern +test: Unit-Tests für Custom Delimiters hinzufügen +``` + +--- + +## CI/CD Pipeline + +### GitHub Actions Workflows + +#### 1. BuildFromDevelop.yml + +**Trigger:** Push oder Pull Request auf `develop` Branch + +**Schritte:** +- Checkout Code +- Setup .NET 8.0 +- Restore Dependencies +- Build (Debug) +- Run Tests + +```yaml +name: BuildFromDevelop +on: + push: + branches: [ develop ] + pull_request: + branches: [ develop ] + +jobs: + build: + runs-on: windows-latest + steps: + - uses: actions/checkout@v4 + - name: Setup .NET + uses: actions/setup-dotnet@v4 + with: + dotnet-version: 8.0.x + - name: Restore + run: dotnet restore + - name: Build + run: dotnet build --no-restore + - name: Test + run: dotnet test --no-build --verbosity normal +``` + +#### 2. BuildFromMaster.yml + +**Trigger:** Push auf `master` Branch + +**Schritte:** Identisch zu BuildFromDevelop, aber für master. + +#### 3. Release.yml + +**Trigger:** GitHub Release wird veröffentlicht + +**Schritte:** +- Checkout Code +- Setup .NET 8.0 +- Restore Dependencies +- Build (Release) +- Create NuGet Package +- Publish to NuGet.org + +```yaml +name: Release +on: + release: + types: + - published + +jobs: + publish-nuget: + runs-on: windows-latest + steps: + - uses: actions/checkout@v4 + - name: Setup .NET + uses: actions/setup-dotnet@v4 + with: + dotnet-version: 8.0.x + - name: Restore + run: dotnet restore + - name: Build + run: dotnet build --configuration Release --no-restore + - name: Pack + run: dotnet pack MbSoftLab.TemplateEngine.Core/MbSoftLab.TemplateEngine.Core.csproj --configuration Release --no-restore -o ./artifacts + - name: Push to NuGet + run: dotnet nuget push ./artifacts/*.nupkg --api-key ${{ secrets.NUGET_API_KEY }} --source https://api.nuget.org/v3/index.json --skip-duplicate +``` + +### Lokale Build-Validierung vor Push + +```bash +# Vor jedem Push ausführen +dotnet restore +dotnet build --configuration Release +dotnet test +dotnet pack --configuration Release +``` + +--- + +## Versionierung + +### Semantic Versioning + +Projekt folgt [Semantic Versioning 2.0.0](https://semver.org/): + +``` +MAJOR.MINOR.PATCH[-PRERELEASE] + +1.0.8-preview2 +│ │ │ └─ Pre-Release-Identifier +│ │ └─── PATCH: Bugfixes +│ └───── MINOR: Neue Features (abwärtskompatibel) +└─────── MAJOR: Breaking Changes +``` + +### Versions-Einstellungen + +In `MbSoftLab.TemplateEngine.Core.csproj`: + +```xml + + 1.0.8.2 + 1.0.8.2 + 1.0.8 + 1.0.8-preview2 + +``` + +**Ändern für neue Version:** +1. `AssemblyVersion` erhöhen (für .NET-Assemblies) +2. `Version` anpassen (NuGet-Package-Hauptversion) +3. `PackageVersion` setzen (inklusive Pre-Release-Suffix falls notwendig) +4. CHANGELOG.md und RELEASENOTES.md aktualisieren + +--- + +## Debugging-Tipps + +### 1. Template-Verarbeitung debuggen + +```csharp +// Breakpoint vor und nach Verarbeitung setzen +var engine = new TemplateEngine(customer, template); + +// Template vor Verarbeitung prüfen +string beforeProcessing = engine.TemplateString; + +string result = engine.CreateStringFromTemplate(); + +// Ergebnis nach Verarbeitung prüfen +Console.WriteLine($"Vor: {beforeProcessing}"); +Console.WriteLine($"Nach: {result}"); +``` + +### 2. Reflection-Debugging + +```csharp +// Properties des DataModels inspizieren +var properties = customer.GetType().GetProperties(); +foreach (var prop in properties) +{ + var value = prop.GetValue(customer); + Console.WriteLine($"{prop.Name}: {value}"); +} +``` + +### 3. Razor-Kompilierung debuggen + +```csharp +try +{ + var razorEngine = new RazorTemplateEngine(); + razorEngine.TemplateString = razorTemplate; + string result = razorEngine.CreateStringFromTemplate(person); +} +catch (RazorEngineCompilationException ex) +{ + Console.WriteLine("Razor-Kompilierungs-Fehler:"); + Console.WriteLine(ex.Message); + Console.WriteLine("Errors:"); + foreach (var error in ex.Errors) + { + Console.WriteLine($" - {error}"); + } +} +``` + +### 4. Unit-Test-Debugging + +```bash +# Einzelnen Test mit Debugging ausführen +dotnet test --filter "MethodName=can_create_a_valid_string_from_template" + +# Visual Studio: Rechtsklick auf Test → "Debug Test" +# VS Code: "Debug Test" im Test Explorer +``` + +### 5. Performance-Analyse + +```csharp +using System.Diagnostics; + +var stopwatch = Stopwatch.StartNew(); +var engine = new TemplateEngine(customer, template); +string result = engine.CreateStringFromTemplate(); +stopwatch.Stop(); + +Console.WriteLine($"Template-Verarbeitung: {stopwatch.ElapsedMilliseconds}ms"); +``` + +--- + +## Erweiterte Entwicklungs-Themen + +### Neue Datentypen hinzufügen + +Um einen neuen Datentyp in `TemplateEngine` zu unterstützen: + +1. **ReplacementAction registrieren** in `PlaceholderValueRaplacer.cs`: + +```csharp +private void RegisterReplacementActions() +{ + _replacementActionCollection + // ... bestehende Actions ... + .AddReplacementAction(typeof(Guid), (placeholderValueName, value) => + ReplaceValueInOutputString(placeholderValueName, (Guid)value)); +} +``` + +2. **Tests hinzufügen** in `TemplateEngineUnitTest.cs`: + +```csharp +[Test] +public void can_handle_guid_values() +{ + var guid = Guid.NewGuid(); + var model = new { Id = guid }; + var engine = new TemplateEngine(model, "ID: ${Id}"); + string result = engine.CreateStringFromTemplate(); + Assert.AreEqual($"ID: {guid}", result); +} +``` + +### Custom Template-Engine erstellen + +Implementieren Sie `ITemplateEngine`: + +```csharp +public class MyCustomEngine : ITemplateEngine +{ + public string OpeningDelimiter { get; set; } + public string CloseingDelimiter { get; set; } + public T TemplateDataModel { get; set; } + public string TemplateString { get; set; } + public string NullStringValue { get; set; } + public CultureInfo CultureInfo { get; set; } + public ITemplateEngineConfig Config { get; set; } + + public string CreateStringFromTemplate(string stringTemplate = null) + { + // Eigene Implementierung + } + + public string CreateStringFromTemplate(T templateDataModel) + { + // Eigene Implementierung + } + + public string CreateStringFromTemplate(T templateDataModel, string stringTemplate) + { + // Eigene Implementierung + } +} +``` + +--- + +## Trouble-Shooting + +### Problem: Build schlägt fehl + +```bash +# Dependencies neu laden +dotnet restore --force +dotnet clean +dotnet build +``` + +### Problem: Tests schlagen fehl + +```bash +# Alle Build-Artefakte löschen +dotnet clean +rm -rf */bin */obj +dotnet build +dotnet test +``` + +### Problem: NuGet-Package kann nicht erstellt werden + +```bash +# Pack mit Verbose-Output +dotnet pack --configuration Release --verbosity detailed +``` + +### Problem: Razor-Templates funktionieren nicht + +**Prüfen:** +1. Erbt DataModel von `TemplateDataModel`? +2. Ist `@Model` in Template korrekt? +3. RazorEngineCore-Dependency installiert? + +```bash +dotnet list package | grep RazorEngineCore +``` + +--- + +## Ressourcen + +### Offizielle Dokumentation + +- [.NET 8.0 Dokumentation](https://learn.microsoft.com/dotnet/core/whats-new/dotnet-8) +- [NuGet Package Dokumentation](https://learn.microsoft.com/nuget/) +- [GitHub Actions Dokumentation](https://docs.github.com/actions) + +### Dependencies + +- [RazorEngineCore](https://github.com/adoconnection/RazorEngineCore) + +### Code-Qualität + +- [CodeFactor](https://www.codefactor.io/repository/github/mbsoftlab/mbsoftlab.templateengine.core) + +--- + +**Letzte Aktualisierung:** Dezember 2025 +**Commit-Referenz:** 5c37e68 diff --git a/docs/examples.md b/docs/examples.md new file mode 100644 index 0000000..61389dd --- /dev/null +++ b/docs/examples.md @@ -0,0 +1,815 @@ +# Beispiele und Tutorials + +**Commit-Referenz:** 5c37e68 +**Dokumentations-Stand:** Dezember 2025 + +--- + +## Inhaltsverzeichnis + +1. [Schnellstart](#schnellstart) +2. [Einfache Beispiele](#einfache-beispiele) +3. [Fortgeschrittene Beispiele](#fortgeschrittene-beispiele) +4. [Razor-Templates](#razor-templates) +5. [Praxis-Szenarien](#praxis-szenarien) +6. [Tipps und Tricks](#tipps-und-tricks) + +--- + +## Schnellstart + +### Installation + +```bash +# NuGet Package Manager +Install-Package MbSoftLab.TemplateEngine.Core + +# .NET CLI +dotnet add package MbSoftLab.TemplateEngine.Core +``` + +### Erstes Beispiel (30 Sekunden) + +```csharp +using MbSoftLab.TemplateEngine.Core; + +// 1. Datenmodell erstellen +var person = new { FirstName = "Max", LastName = "Mustermann" }; + +// 2. Template definieren +string template = "Hallo ${FirstName} ${LastName}!"; + +// 3. Template-Engine initialisieren +var engine = new TemplateEngine(person, template); + +// 4. String erstellen +string result = engine.CreateStringFromTemplate(); + +Console.WriteLine(result); +// Output: Hallo Max Mustermann! +``` + +--- + +## Einfache Beispiele + +### Beispiel 1: Grundlegende Verwendung + +```csharp +using MbSoftLab.TemplateEngine.Core; + +public class Customer +{ + public string Name { get; set; } + public string Email { get; set; } + public int OrderCount { get; set; } +} + +// Daten +var customer = new Customer +{ + Name = "Anna Schmidt", + Email = "anna@example.com", + OrderCount = 5 +}; + +// Template +string template = @" +Kunde: ${Name} +E-Mail: ${Email} +Anzahl Bestellungen: ${OrderCount} +"; + +// Verarbeitung +var engine = new TemplateEngine(customer, template); +string result = engine.CreateStringFromTemplate(); + +Console.WriteLine(result); +``` + +**Output:** +``` +Kunde: Anna Schmidt +E-Mail: anna@example.com +Anzahl Bestellungen: 5 +``` + +--- + +### Beispiel 2: Property-Injection + +```csharp +// Engine ohne Daten erstellen +var engine = new TemplateEngine(); + +// Später Daten setzen +engine.TemplateDataModel = customer; +engine.TemplateString = "Hallo ${Name}!"; + +// Verarbeiten +string result = engine.CreateStringFromTemplate(); +``` + +**Vorteil:** Flexibel für Dependency Injection und Testszenarien. + +--- + +### Beispiel 3: Custom Delimiters + +```csharp +var customer = new Customer { Name = "Bob" }; + +var engine = new TemplateEngine(customer, "[[Name]]"); +engine.OpeningDelimiter = "[["; +engine.CloseingDelimiter = "]]"; + +string result = engine.CreateStringFromTemplate(); +// Output: Bob +``` + +**Use-Case:** Konflikte mit anderen Template-Syntaxen vermeiden (z.B. Angular, Vue.js). + +--- + +### Beispiel 4: NULL-Wert-Behandlung + +```csharp +var customer = new Customer +{ + Name = "Charlie", + Email = null // NULL-Wert +}; + +var engine = new TemplateEngine(customer, "E-Mail: ${Email}"); +string result = engine.CreateStringFromTemplate(); +// Output: E-Mail: NULL + +// Custom NULL-String +engine.NullStringValue = "Keine Angabe"; +result = engine.CreateStringFromTemplate(); +// Output: E-Mail: Keine Angabe +``` + +--- + +### Beispiel 5: Kultur-spezifische Formatierung + +```csharp +public class Product +{ + public string Name { get; set; } + public decimal Price { get; set; } + public DateTime Available { get; set; } +} + +var product = new Product +{ + Name = "Laptop", + Price = 1299.99m, + Available = new DateTime(2025, 12, 24) +}; + +// Deutsche Formatierung +var engineDE = new TemplateEngine(product, + "Produkt: ${Name}\nPreis: ${Price}\nVerfügbar ab: ${Available}"); +engineDE.CultureInfo = System.Globalization.CultureInfo.GetCultureInfo("de-DE"); +Console.WriteLine(engineDE.CreateStringFromTemplate()); + +// Output: +// Produkt: Laptop +// Preis: 1299,99 +// Verfügbar ab: 24.12.2025 00:00:00 +``` + +--- + +### Beispiel 6: Template aus Datei laden + +**Template-Datei:** `email-template.txt` +``` +Sehr geehrte/r ${Name}, + +vielen Dank für Ihre ${OrderCount} Bestellungen. + +Mit freundlichen Grüßen +Ihr Team +``` + +**C#-Code:** +```csharp +var customer = new Customer +{ + Name = "Diana Weber", + OrderCount = 3 +}; + +var engine = new TemplateEngine(customer); +engine.LoadTemplateFromFile("email-template.txt"); +string result = engine.CreateStringFromTemplate(); + +Console.WriteLine(result); +``` + +--- + +### Beispiel 7: Methoden in Templates + +```csharp +public class Invoice +{ + public string InvoiceNumber { get; set; } + public decimal NetAmount { get; set; } + public decimal TaxRate { get; set; } + + // Parameterlose Methode + public decimal GetGrossAmount() + { + return NetAmount * (1 + TaxRate); + } + + public string GetFormattedInvoiceNumber() + { + return $"INV-{InvoiceNumber}"; + } +} + +var invoice = new Invoice +{ + InvoiceNumber = "2025-001", + NetAmount = 100m, + TaxRate = 0.19m +}; + +string template = @" +Rechnungsnummer: ${GetFormattedInvoiceNumber()} +Nettobetrag: ${NetAmount} +Bruttobetrag: ${GetGrossAmount()} +"; + +var engine = new TemplateEngine(invoice, template); +string result = engine.CreateStringFromTemplate(); +``` + +**Output:** +``` +Rechnungsnummer: INV-2025-001 +Nettobetrag: 100 +Bruttobetrag: 119 +``` + +**Wichtig:** Nur parameterlose öffentliche Methoden funktionieren! + +--- + +## Fortgeschrittene Beispiele + +### Beispiel 8: JSON-Daten verwenden + +```csharp +string jsonData = @" +{ + ""Name"": ""Eve Johnson"", + ""Email"": ""eve@example.com"", + ""OrderCount"": 7 +}"; + +var engine = new TemplateEngine(); +engine.TemplateString = "Kunde ${Name} hat ${OrderCount} Bestellungen."; + +string result = engine.CreateStringFromTemplateWithJson(jsonData); +// Output: Kunde Eve Johnson hat 7 Bestellungen. +``` + +--- + +### Beispiel 9: Konfigurationsobjekt verwenden + +```csharp +var config = new TemplateEngineConfig +{ + OpeningDelimiter = "{{", + CloseingDelimiter = "}}", + NullStringValue = "---", + TemplateString = "{{Name}} ({{Email}})", + TemplateDataModel = customer, + CultureInfo = System.Globalization.CultureInfo.GetCultureInfo("de-DE") +}; + +var engine = new TemplateEngine(); +engine.Config = config; + +string result = engine.CreateStringFromTemplate(); +``` + +**Vorteil:** Wiederverwendbare Konfiguration, ideal für Unit-Tests. + +--- + +### Beispiel 10: Mehrere Templates mit gleichen Daten + +```csharp +var customer = new Customer { Name = "Frank", Email = "frank@test.de" }; + +var emailEngine = new TemplateEngine(customer); +var smsEngine = new TemplateEngine(customer); + +// E-Mail-Template +emailEngine.TemplateString = "Hallo ${Name}, Ihre E-Mail: ${Email}"; +string email = emailEngine.CreateStringFromTemplate(); + +// SMS-Template (kürzer) +smsEngine.TemplateString = "Hallo ${Name}!"; +string sms = smsEngine.CreateStringFromTemplate(); +``` + +--- + +### Beispiel 11: Dynamisches Template-Switching + +```csharp +var customer = new Customer { Name = "Grace", OrderCount = 10 }; + +var engine = new TemplateEngine(customer); + +// Verschiedene Templates je nach Kontext +string template = customer.OrderCount > 5 + ? "Vielen Dank für Ihre ${OrderCount} Bestellungen, ${Name}!" + : "Hallo ${Name}, Sie haben ${OrderCount} Bestellungen."; + +engine.TemplateString = template; +string result = engine.CreateStringFromTemplate(); +``` + +--- + +## Razor-Templates + +### Beispiel 12: Einfaches Razor-Template + +```csharp +using MbSoftLab.TemplateEngine.Core; + +public class Person : TemplateDataModel +{ + public string FirstName { get; set; } + public string LastName { get; set; } + public int Age { get; set; } +} + +var person = new Person +{ + FirstName = "Hans", + LastName = "Müller", + Age = 35 +}; + +var engine = new RazorTemplateEngine(); + +string razorTemplate = @" +

    @Model.FirstName @Model.LastName

    +

    Alter: @Model.Age Jahre

    +"; + +engine.TemplateString = razorTemplate; +string html = engine.CreateStringFromTemplate(person); +``` + +**Output:** +```html +

    Hans Müller

    +

    Alter: 35 Jahre

    +``` + +--- + +### Beispiel 13: Razor mit Bedingungen + +```csharp +public class User : TemplateDataModel +{ + public string Name { get; set; } + public bool IsPremium { get; set; } + public int Points { get; set; } +} + +var user = new User +{ + Name = "Ines", + IsPremium = true, + Points = 1250 +}; + +string template = @" +
    +

    @Model.Name

    + + @if (Model.IsPremium) { + Premium-Mitglied + } + +

    Punkte: @Model.Points

    + + @if (Model.Points > 1000) { +

    Sie haben genug Punkte für eine Belohnung!

    + } +
    +"; + +var engine = new RazorTemplateEngine(user, template); +string html = engine.CreateStringFromTemplate(); +``` + +--- + +### Beispiel 14: Razor mit Listen (foreach) + +```csharp +public class ShoppingList : TemplateDataModel +{ + public string Owner { get; set; } + public List Items { get; set; } +} + +var list = new ShoppingList +{ + Owner = "Julia", + Items = new List { "Milch", "Brot", "Eier", "Butter" } +}; + +string template = @" +

    Einkaufsliste von @Model.Owner

    +
      +@foreach(var item in Model.Items) { +
    • @item
    • +} +
    +

    Gesamt: @Model.Items.Count Artikel

    +"; + +var engine = new RazorTemplateEngine(list, template); +string html = engine.CreateStringFromTemplate(); +``` + +**Output:** +```html +

    Einkaufsliste von Julia

    +
      +
    • Milch
    • +
    • Brot
    • +
    • Eier
    • +
    • Butter
    • +
    +

    Gesamt: 4 Artikel

    +``` + +--- + +### Beispiel 15: Razor mit verschachtelten Objekten + +```csharp +public class Address : TemplateDataModel
    +{ + public string Street { get; set; } + public string City { get; set; } + public string PostCode { get; set; } +} + +public class Customer : TemplateDataModel +{ + public string Name { get; set; } + public Address Address { get; set; } + public List Orders { get; set; } +} + +public class Order : TemplateDataModel +{ + public int Id { get; set; } + public decimal Total { get; set; } +} + +var customer = new Customer +{ + Name = "Klaus Werner", + Address = new Address + { + Street = "Hauptstraße 1", + City = "München", + PostCode = "80331" + }, + Orders = new List + { + new Order { Id = 1, Total = 49.99m }, + new Order { Id = 2, Total = 129.50m } + } +}; + +string template = @" +
    +

    @Model.Name

    + +
    +

    Adresse

    +

    @Model.Address.Street
    + @Model.Address.PostCode @Model.Address.City

    +
    + +
    +

    Bestellungen

    + + + + + + @foreach(var order in Model.Orders) { + + + + + } + +
    IDSumme
    @order.Id@order.Total.ToString(""C"")
    +
    +
    +"; + +var engine = new RazorTemplateEngine(customer, template); +string html = engine.CreateStringFromTemplate(); +``` + +--- + +### Beispiel 16: Razor-Template aus Datei laden + +**Template-Datei:** `invoice.cshtml` +```cshtml +@* Rechnungs-Template *@ + + + Rechnung @Model.InvoiceNumber + + +

    Rechnung @Model.InvoiceNumber

    + + + @foreach(var item in Model.Items) { + + + + + + } +
    @item.ProductName@item.Quantity@item.Price.ToString("C")
    + +

    Gesamt: @Model.Total.ToString("C")

    + + +``` + +**C#-Code:** +```csharp +var invoice = new Invoice +{ + InvoiceNumber = "2025-123", + Items = items, + Total = 299.99m +}; + +var engine = new RazorTemplateEngine(invoice); +engine.LoadTemplateFromFile("invoice.cshtml"); +string html = engine.CreateStringFromTemplate(); + +// HTML in Datei speichern +File.WriteAllText("invoice-2025-123.html", html); +``` + +--- + +## Praxis-Szenarien + +### Szenario 1: E-Mail-Versand + +```csharp +public class EmailService +{ + private readonly ITemplateEngine _engine; + + public EmailService() + { + _engine = new TemplateEngine(); + } + + public string GenerateWelcomeEmail(string userName, string email) + { + var data = new EmailData + { + UserName = userName, + Email = email, + RegistrationDate = DateTime.Now + }; + + _engine.LoadTemplateFromFile("templates/welcome-email.txt"); + return _engine.CreateStringFromTemplate(data); + } +} + +public class EmailData +{ + public string UserName { get; set; } + public string Email { get; set; } + public DateTime RegistrationDate { get; set; } +} +``` + +**Template:** `welcome-email.txt` +``` +Hallo ${UserName}, + +herzlich willkommen! + +Ihre E-Mail-Adresse: ${Email} +Registriert am: ${RegistrationDate} + +Viele Grüße +Ihr Team +``` + +--- + +### Szenario 2: Report-Generierung + +```csharp +public class ReportGenerator +{ + public string GenerateMonthlyReport(ReportData data) + { + var config = new TemplateEngineConfig + { + TemplateDataModel = data, + CultureInfo = CultureInfo.GetCultureInfo("de-DE"), + NullStringValue = "Keine Daten" + }; + + var engine = new TemplateEngine { Config = config }; + engine.LoadTemplateFromFile("templates/monthly-report.txt"); + + return engine.CreateStringFromTemplate(); + } +} +``` + +--- + +### Szenario 3: HTML-Berichte mit Razor + +```csharp +public class HtmlReportService +{ + public void GenerateAndSaveReport(SalesData data, string outputPath) + { + var engine = new RazorTemplateEngine(); + engine.LoadTemplateFromFile("templates/sales-report.cshtml"); + + string html = engine.CreateStringFromTemplate(data); + + File.WriteAllText(outputPath, html); + } +} + +public class SalesData : TemplateDataModel +{ + public string Month { get; set; } + public decimal Revenue { get; set; } + public List TopSales { get; set; } +} +``` + +--- + +### Szenario 4: Konfigurations-Dateien generieren + +```csharp +public class ConfigGenerator +{ + public void GenerateAppConfig(AppSettings settings) + { + string template = @" +server.host=${Host} +server.port=${Port} +database.connection=${DatabaseConnection} +logging.level=${LogLevel} +"; + + var engine = new TemplateEngine(settings, template); + string config = engine.CreateStringFromTemplate(); + + File.WriteAllText("app.config", config); + } +} +``` + +--- + +## Tipps und Tricks + +### Tipp 1: Performance bei vielen gleichen Templates + +```csharp +// ❌ Nicht effizient +for (int i = 0; i < 1000; i++) { + var engine = new TemplateEngine(customers[i], template); + results[i] = engine.CreateStringFromTemplate(); +} + +// ✅ Effizient +var engine = new TemplateEngine(); +engine.TemplateString = template; +for (int i = 0; i < 1000; i++) { + results[i] = engine.CreateStringFromTemplate(customers[i]); +} +``` + +--- + +### Tipp 2: Template-Validierung + +```csharp +public bool ValidateTemplate(string template, Type modelType) +{ + try + { + var instance = Activator.CreateInstance(modelType); + var engine = new TemplateEngine(instance, template); + engine.CreateStringFromTemplate(); + return true; + } + catch + { + return false; + } +} +``` + +--- + +### Tipp 3: Collections mit TemplateEngine (Workaround) + +```csharp +// Statt Collections direkt zu verwenden +public class Report +{ + public string Item1 { get; set; } + public string Item2 { get; set; } + public string Item3 { get; set; } + + // Oder: Methode mit String-Join + public string GetAllItems() + { + return string.Join(", ", new[] { Item1, Item2, Item3 }); + } +} + +string template = "Items: ${GetAllItems()}"; +``` + +**Besser:** Verwenden Sie `RazorTemplateEngine` für echte Listen! + +--- + +### Tipp 4: Thread-Sicherheit + +```csharp +// ❌ Nicht thread-safe +var sharedEngine = new TemplateEngine(); + +// ✅ Thread-safe: Jeder Thread eigene Instanz +ThreadPool.QueueUserWorkItem(_ => { + var engine = new TemplateEngine(customer, template); + var result = engine.CreateStringFromTemplate(); +}); +``` + +--- + +### Tipp 5: Fehlerbehandlung + +```csharp +try +{ + var engine = new TemplateEngine(customer, template); + string result = engine.CreateStringFromTemplate(); +} +catch (NotSupportedException ex) +{ + Console.WriteLine($"Nicht unterstützter Typ: {ex.Message}"); + // Fallback zu RazorTemplateEngine +} +catch (Exception ex) +{ + Console.WriteLine($"Fehler bei Template-Verarbeitung: {ex.Message}"); +} +``` + +--- + +**Letzte Aktualisierung:** Dezember 2025 +**Commit-Referenz:** 5c37e68 From 8248ee3d3fdab24b99efa8de04fe9021464a1de2 Mon Sep 17 00:00:00 2001 From: Justin <50733221+jupre003@users.noreply.github.com> Date: Sat, 6 Dec 2025 16:19:59 +0100 Subject: [PATCH 28/28] feat: Add Razor support as an optional extension to TemplateEngine.Core (#12) * Add Razor support as an optional extension to TemplateEngine.Core - Introduced MbSoftLab.TemplateEngine.Core.Razor project with RazorTemplateEngine implementation. - Updated project references in existing projects to include the new Razor extension. - Removed Razor dependencies from core classes and adjusted documentation to reflect optional usage. - Enhanced README and other documentation files to guide users on installing and using the Razor extension. * Disable package cache and specify solution file for restore, build, and test steps in CI workflows --- .github/workflows/BuildFromDevelop.yml | 9 +++-- .github/workflows/BuildFromMaster.yml | 8 ++-- .github/workflows/Release.yml | 6 +-- .../Documentation.xml | 8 ++++ ...MbSoftLab.TemplateEngine.Core.Razor.csproj | 37 +++++++++++++++++++ MbSoftLab.TemplateEngine.Core.Razor/README.md | 32 ++++++++++++++++ .../RazorTemplateEngine.cs | 4 +- ...MbSoftLab.TemplateEngine.Core.Tests.csproj | 1 + MbSoftLab.TemplateEngine.Core.sln | 22 +++++++++++ .../MbSoftLab.TemplateEngine.Core.csproj | 1 - .../TemplateDataModel.cs | 7 ++-- .../MbSoftlab.TemplateEngine.Core.Demo.csproj | 1 + README.md | 9 ++++- docs/README.md | 13 +++++-- docs/architecture.md | 9 +++-- docs/development.md | 28 +++++++++++--- docs/examples.md | 10 ++++- 17 files changed, 172 insertions(+), 33 deletions(-) create mode 100644 MbSoftLab.TemplateEngine.Core.Razor/Documentation.xml create mode 100644 MbSoftLab.TemplateEngine.Core.Razor/MbSoftLab.TemplateEngine.Core.Razor.csproj create mode 100644 MbSoftLab.TemplateEngine.Core.Razor/README.md rename {MbSoftLab.TemplateEngine.Core => MbSoftLab.TemplateEngine.Core.Razor}/RazorTemplateEngine.cs (99%) diff --git a/.github/workflows/BuildFromDevelop.yml b/.github/workflows/BuildFromDevelop.yml index 33b060f..a9fd741 100644 --- a/.github/workflows/BuildFromDevelop.yml +++ b/.github/workflows/BuildFromDevelop.yml @@ -20,10 +20,11 @@ jobs: uses: actions/setup-dotnet@v4 with: dotnet-version: 8.0.x - cache: true + # Disable package cache to avoid lock file requirement + cache: false - name: Restore - run: dotnet restore + run: dotnet restore MbSoftLab.TemplateEngine.Core.sln - name: Build - run: dotnet build --configuration Release --no-restore + run: dotnet build MbSoftLab.TemplateEngine.Core.sln --configuration Release --no-restore - name: Test - run: dotnet test --no-restore --verbosity normal + run: dotnet test MbSoftLab.TemplateEngine.Core.sln --no-restore --verbosity normal diff --git a/.github/workflows/BuildFromMaster.yml b/.github/workflows/BuildFromMaster.yml index 44af805..e7300a8 100644 --- a/.github/workflows/BuildFromMaster.yml +++ b/.github/workflows/BuildFromMaster.yml @@ -20,10 +20,10 @@ jobs: uses: actions/setup-dotnet@v4 with: dotnet-version: 8.0.x - cache: true + cache: false - name: Restore - run: dotnet restore + run: dotnet restore MbSoftLab.TemplateEngine.Core.sln - name: Build - run: dotnet build --configuration Release --no-restore + run: dotnet build MbSoftLab.TemplateEngine.Core.sln --configuration Release --no-restore - name: Test - run: dotnet test --no-restore --verbosity normal + run: dotnet test MbSoftLab.TemplateEngine.Core.sln --no-restore --verbosity normal diff --git a/.github/workflows/Release.yml b/.github/workflows/Release.yml index ac522ea..59d6f05 100644 --- a/.github/workflows/Release.yml +++ b/.github/workflows/Release.yml @@ -14,11 +14,11 @@ jobs: uses: actions/setup-dotnet@v4 with: dotnet-version: 8.0.x - cache: true + cache: false - name: Restore - run: dotnet restore + run: dotnet restore MbSoftLab.TemplateEngine.Core.sln - name: Build - run: dotnet build --configuration Release --no-restore + run: dotnet build MbSoftLab.TemplateEngine.Core.sln --configuration Release --no-restore - name: Pack run: dotnet pack MbSoftLab.TemplateEngine.Core/MbSoftLab.TemplateEngine.Core.csproj --configuration Release --no-restore -o ./artifacts - name: Push to NuGet diff --git a/MbSoftLab.TemplateEngine.Core.Razor/Documentation.xml b/MbSoftLab.TemplateEngine.Core.Razor/Documentation.xml new file mode 100644 index 0000000..a5c2363 --- /dev/null +++ b/MbSoftLab.TemplateEngine.Core.Razor/Documentation.xml @@ -0,0 +1,8 @@ + + + + MbSoftLab.TemplateEngine.Core.Razor + + + + diff --git a/MbSoftLab.TemplateEngine.Core.Razor/MbSoftLab.TemplateEngine.Core.Razor.csproj b/MbSoftLab.TemplateEngine.Core.Razor/MbSoftLab.TemplateEngine.Core.Razor.csproj new file mode 100644 index 0000000..4d9a9e0 --- /dev/null +++ b/MbSoftLab.TemplateEngine.Core.Razor/MbSoftLab.TemplateEngine.Core.Razor.csproj @@ -0,0 +1,37 @@ + + + + net8.0 + 1.1.0.0 + 1.1.0.0 + 1.1.0 + 1.1.0-preview + Razor-enabled extension for MbSoftLab.TemplateEngine.Core providing RazorTemplateEngine. + true + true + Template Engine Razor RazorEngineCore Html + MbSoftLab.TemplateEngine.Core.Razor + MbSoftLab + MbSoftLab + MIT + © 2021 - 2025 MbSoftLab + MbSoftLabLogo.png + https://github.com/mbsoftlab/MbSoftLab.TemplateEngine.Core + https://github.com/mbsoftlab/MbSoftLab.TemplateEngine.Core + Git + Documentation.xml + + + + + + + + + + True + + + + + diff --git a/MbSoftLab.TemplateEngine.Core.Razor/README.md b/MbSoftLab.TemplateEngine.Core.Razor/README.md new file mode 100644 index 0000000..0c8c0aa --- /dev/null +++ b/MbSoftLab.TemplateEngine.Core.Razor/README.md @@ -0,0 +1,32 @@ +# MbSoftLab.TemplateEngine.Core.Razor + +Optionales Erweiterungspaket für MbSoftLab.TemplateEngine.Core, das die `RazorTemplateEngine` bereitstellt. + +## Installation + +```bash +# .NET CLI +dotnet add package MbSoftLab.TemplateEngine.Core.Razor + +# Oder Projekt-Referenz (Monorepo) +dotnet add .csproj reference MbSoftLab.TemplateEngine.Core.Razor/MbSoftLab.TemplateEngine.Core.Razor.csproj +``` + +## Verwendung + +```csharp +using MbSoftLab.TemplateEngine.Core; + +public class Person : TemplateDataModel +{ + public string FirstName { get; set; } +} + +var person = new Person { FirstName = "Anna" }; + +var engine = new RazorTemplateEngine(); +engine.TemplateString = "

    @Model.FirstName

    "; +string html = engine.CreateStringFromTemplate(person); +``` + +Hinweis: `TemplateDataModel` ist nun eine einfache Klasse im Core (ohne Razor-Basis). Die Razor-Engine erhält intern `Model` als Datenmodell (`template.Run(TemplateDataModel?.Model)`). diff --git a/MbSoftLab.TemplateEngine.Core/RazorTemplateEngine.cs b/MbSoftLab.TemplateEngine.Core.Razor/RazorTemplateEngine.cs similarity index 99% rename from MbSoftLab.TemplateEngine.Core/RazorTemplateEngine.cs rename to MbSoftLab.TemplateEngine.Core.Razor/RazorTemplateEngine.cs index dcc6fee..b802f0b 100644 --- a/MbSoftLab.TemplateEngine.Core/RazorTemplateEngine.cs +++ b/MbSoftLab.TemplateEngine.Core.Razor/RazorTemplateEngine.cs @@ -1,4 +1,4 @@ -using RazorEngineCore; +using RazorEngineCore; using System; using System.ComponentModel; using System.Globalization; @@ -86,4 +86,4 @@ public string CreateStringFromTemplate(T templateDataModel, string csHtmlTemplat TemplateString = csHtmlTemplate; return CreateStringFromTemplate(); } -} \ No newline at end of file +} diff --git a/MbSoftLab.TemplateEngine.Core.Tests/MbSoftLab.TemplateEngine.Core.Tests.csproj b/MbSoftLab.TemplateEngine.Core.Tests/MbSoftLab.TemplateEngine.Core.Tests.csproj index 7dfaf19..d184bec 100644 --- a/MbSoftLab.TemplateEngine.Core.Tests/MbSoftLab.TemplateEngine.Core.Tests.csproj +++ b/MbSoftLab.TemplateEngine.Core.Tests/MbSoftLab.TemplateEngine.Core.Tests.csproj @@ -14,6 +14,7 @@ + diff --git a/MbSoftLab.TemplateEngine.Core.sln b/MbSoftLab.TemplateEngine.Core.sln index aa7f849..3377ad7 100644 --- a/MbSoftLab.TemplateEngine.Core.sln +++ b/MbSoftLab.TemplateEngine.Core.sln @@ -7,6 +7,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MbSoftLab.TemplateEngine.Co EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MbSoftLab.TemplateEngine.Core", "MbSoftLab.TemplateEngine.Core\MbSoftLab.TemplateEngine.Core.csproj", "{CA5BFFAC-ADA4-478B-8B13-B3AF81FE4A05}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MbSoftLab.TemplateEngine.Core.Razor", "MbSoftLab.TemplateEngine.Core.Razor\MbSoftLab.TemplateEngine.Core.Razor.csproj", "{A9E18D5A-4B79-4C49-BB3A-1E8D0B0D7F1E}" +EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MbSoftlab.TemplateEngine.Core.Demo", "MbSoftlab.TemplateEngine.Core.Demo\MbSoftlab.TemplateEngine.Core.Demo.csproj", "{159ED0CF-FB05-4F88-A442-90890814E6A8}" EndProject Global @@ -63,6 +65,26 @@ Global {CA5BFFAC-ADA4-478B-8B13-B3AF81FE4A05}.Release|x64.Build.0 = Release|Any CPU {CA5BFFAC-ADA4-478B-8B13-B3AF81FE4A05}.Release|x86.ActiveCfg = Release|Any CPU {CA5BFFAC-ADA4-478B-8B13-B3AF81FE4A05}.Release|x86.Build.0 = Release|Any CPU + {A9E18D5A-4B79-4C49-BB3A-1E8D0B0D7F1E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A9E18D5A-4B79-4C49-BB3A-1E8D0B0D7F1E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A9E18D5A-4B79-4C49-BB3A-1E8D0B0D7F1E}.Debug|ARM.ActiveCfg = Debug|Any CPU + {A9E18D5A-4B79-4C49-BB3A-1E8D0B0D7F1E}.Debug|ARM.Build.0 = Debug|Any CPU + {A9E18D5A-4B79-4C49-BB3A-1E8D0B0D7F1E}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {A9E18D5A-4B79-4C49-BB3A-1E8D0B0D7F1E}.Debug|ARM64.Build.0 = Debug|Any CPU + {A9E18D5A-4B79-4C49-BB3A-1E8D0B0D7F1E}.Debug|x64.ActiveCfg = Debug|Any CPU + {A9E18D5A-4B79-4C49-BB3A-1E8D0B0D7F1E}.Debug|x64.Build.0 = Debug|Any CPU + {A9E18D5A-4B79-4C49-BB3A-1E8D0B0D7F1E}.Debug|x86.ActiveCfg = Debug|Any CPU + {A9E18D5A-4B79-4C49-BB3A-1E8D0B0D7F1E}.Debug|x86.Build.0 = Debug|Any CPU + {A9E18D5A-4B79-4C49-BB3A-1E8D0B0D7F1E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A9E18D5A-4B79-4C49-BB3A-1E8D0B0D7F1E}.Release|Any CPU.Build.0 = Release|Any CPU + {A9E18D5A-4B79-4C49-BB3A-1E8D0B0D7F1E}.Release|ARM.ActiveCfg = Release|Any CPU + {A9E18D5A-4B79-4C49-BB3A-1E8D0B0D7F1E}.Release|ARM.Build.0 = Release|Any CPU + {A9E18D5A-4B79-4C49-BB3A-1E8D0B0D7F1E}.Release|ARM64.ActiveCfg = Release|Any CPU + {A9E18D5A-4B79-4C49-BB3A-1E8D0B0D7F1E}.Release|ARM64.Build.0 = Release|Any CPU + {A9E18D5A-4B79-4C49-BB3A-1E8D0B0D7F1E}.Release|x64.ActiveCfg = Release|Any CPU + {A9E18D5A-4B79-4C49-BB3A-1E8D0B0D7F1E}.Release|x64.Build.0 = Release|Any CPU + {A9E18D5A-4B79-4C49-BB3A-1E8D0B0D7F1E}.Release|x86.ActiveCfg = Release|Any CPU + {A9E18D5A-4B79-4C49-BB3A-1E8D0B0D7F1E}.Release|x86.Build.0 = Release|Any CPU {159ED0CF-FB05-4F88-A442-90890814E6A8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {159ED0CF-FB05-4F88-A442-90890814E6A8}.Debug|Any CPU.Build.0 = Debug|Any CPU {159ED0CF-FB05-4F88-A442-90890814E6A8}.Debug|ARM.ActiveCfg = Debug|Any CPU diff --git a/MbSoftLab.TemplateEngine.Core/MbSoftLab.TemplateEngine.Core.csproj b/MbSoftLab.TemplateEngine.Core/MbSoftLab.TemplateEngine.Core.csproj index 4601007..ea37988 100644 --- a/MbSoftLab.TemplateEngine.Core/MbSoftLab.TemplateEngine.Core.csproj +++ b/MbSoftLab.TemplateEngine.Core/MbSoftLab.TemplateEngine.Core.csproj @@ -31,7 +31,6 @@ - diff --git a/MbSoftLab.TemplateEngine.Core/TemplateDataModel.cs b/MbSoftLab.TemplateEngine.Core/TemplateDataModel.cs index a61384a..158156a 100644 --- a/MbSoftLab.TemplateEngine.Core/TemplateDataModel.cs +++ b/MbSoftLab.TemplateEngine.Core/TemplateDataModel.cs @@ -1,12 +1,11 @@ -using RazorEngineCore; -using System.Text.Json.Serialization; +using System.Text.Json.Serialization; namespace MbSoftLab.TemplateEngine.Core; -public class TemplateDataModel : RazorEngineTemplateBase +public class TemplateDataModel { [JsonIgnore] - public new T Model { get; set; } + public T Model { get; set; } public string GetNullstringValue() { diff --git a/MbSoftlab.TemplateEngine.Core.Demo/MbSoftlab.TemplateEngine.Core.Demo.csproj b/MbSoftlab.TemplateEngine.Core.Demo/MbSoftlab.TemplateEngine.Core.Demo.csproj index d7f13de..0a879a5 100644 --- a/MbSoftlab.TemplateEngine.Core.Demo/MbSoftlab.TemplateEngine.Core.Demo.csproj +++ b/MbSoftlab.TemplateEngine.Core.Demo/MbSoftlab.TemplateEngine.Core.Demo.csproj @@ -11,6 +11,7 @@ + diff --git a/README.md b/README.md index 7224d65..6478641 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,13 @@ string result = engine.CreateStringFromTemplate(); // Output: "Hallo Max Mustermann!" ``` -### Razor-Template-Beispiel +### Razor-Template-Beispiel (optional) + +Installieren Sie zusätzlich das optionale Paket: + +```bash +dotnet add package MbSoftLab.TemplateEngine.Core.Razor +``` ```csharp public class Person : TemplateDataModel @@ -44,6 +50,7 @@ var person = new Person { Tags = new List { "Developer", "Designer" } }; +// Razor steht erst nach Installation von MbSoftLab.TemplateEngine.Core.Razor zur Verfügung var engine = new RazorTemplateEngine(); engine.TemplateString = @"

    @Model.FirstName

    diff --git a/docs/README.md b/docs/README.md index ed1cd88..7cbf665 100644 --- a/docs/README.md +++ b/docs/README.md @@ -11,8 +11,8 @@ Willkommen zur offiziellen Dokumentation der **MbSoftLab.TemplateEngine.Core** Bibliothek - einer leistungsstarken und flexiblen Template-Engine für .NET 8.0. Diese Bibliothek bietet zwei verschiedene Ansätze zur Template-Verarbeitung: -- **TemplateEngine** - Schnell und einfach für String-basierte Templates -- **RazorTemplateEngine** - Mächtig und flexibel für komplexe HTML-Templates mit Razor-Syntax +- **TemplateEngine** – Schnell und einfach für String-basierte Templates +- **RazorTemplateEngine** – Mächtig und flexibel für komplexe HTML-Templates mit Razor-Syntax (optional, verfügbar nach Installation von `MbSoftLab.TemplateEngine.Core.Razor`) --- @@ -74,6 +74,12 @@ Install-Package MbSoftLab.TemplateEngine.Core dotnet add package MbSoftLab.TemplateEngine.Core ``` +Optional: Razor-Unterstützung installieren + +```bash +dotnet add package MbSoftLab.TemplateEngine.Core.Razor +``` + ### Erstes Beispiel ```csharp @@ -121,10 +127,11 @@ var engine = new TemplateEngine(customer, "Hallo ${Name}!"); → Siehe [Einfache Beispiele](/docs/examples/#einfache-beispiele) -### 2. Komplexe HTML-Templates +### 2. Komplexe HTML-Templates (optional) Für dynamische HTML-Generierung mit Schleifen, Bedingungen und verschachtelten Objekten. ```csharp +// Razor steht erst nach Installation von MbSoftLab.TemplateEngine.Core.Razor zur Verfügung var engine = new RazorTemplateEngine(); engine.TemplateString = "@foreach(var item in Model.Items) {
  • @item
  • }"; ``` diff --git a/docs/architecture.md b/docs/architecture.md index 7103f46..119d486 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -20,7 +20,7 @@ MbSoftLab.TemplateEngine.Core ist eine .NET 8.0 Bibliothek, die zwei verschiedene Template-Engine-Implementierungen bereitstellt: 1. **TemplateEngine** - Einfacher, schneller String-basierter Template-Engine -2. **RazorTemplateEngine** - Komplexer Razor-basierter Template-Engine für HTML +2. **RazorTemplateEngine** - Komplexer Razor-basierter Template-Engine für HTML (bereitgestellt durch das optionale Paket `MbSoftLab.TemplateEngine.Core.Razor`) Beide implementieren das gemeinsame `ITemplateEngine` Interface. @@ -39,7 +39,7 @@ graph TB subgraph "MbSoftLab.TemplateEngine.Core" B[ITemplateEngine<T>] C[TemplateEngine<T>] - D[RazorTemplateEngine<T>] + D[[RazorTemplateEngine<T>]] E[TemplateDataModelProcessor] F[PlaceholderValueReplacer] G[ReplacementActionCollection] @@ -48,7 +48,8 @@ graph TB J[TemplateEngineExtensions] end - subgraph "External Dependencies" + subgraph "MbSoftLab.TemplateEngine.Core.Razor (optional)" + D K[RazorEngineCore] end @@ -125,7 +126,7 @@ classDiagram ITemplateEngine~T~ <|.. TemplateEngine~T~ ITemplateEngine~T~ <|.. RazorTemplateEngine~T~ ITemplateEngineConfig~T~ <|.. TemplateEngineConfig~T~ - RazorEngineTemplateBase <|-- TemplateDataModel~T~ + %% Core ist von Razor entkoppelt; kein RazorEngineTemplateBase TemplateEngine~T~ --> ITemplateEngineConfig~T~ RazorTemplateEngine~T~ --> ITemplateEngineConfig~T~ RazorTemplateEngine~T~ --> TemplateDataModel~T~ diff --git a/docs/development.md b/docs/development.md index 529f41c..50bb091 100644 --- a/docs/development.md +++ b/docs/development.md @@ -66,11 +66,10 @@ MbSoftLab.TemplateEngine.Core/ │ ├── BuildFromDevelop.yml │ ├── BuildFromMaster.yml │ └── Release.yml -├── MbSoftLab.TemplateEngine.Core/ # Haupt-Bibliothek +├── MbSoftLab.TemplateEngine.Core/ # Haupt-Bibliothek (ohne Razor-Abhängigkeit) │ ├── ITemplateEngine.cs # Interface für Template-Engines │ ├── TemplateEngine.cs # Simple Template-Engine -│ ├── RazorTemplateEngine.cs # Razor-basierte Engine -│ ├── TemplateDataModel.cs # Basis-Klasse für Razor-Models +│ ├── TemplateDataModel.cs # Datenmodell (ohne Razor-Basisklasse) │ ├── TemplateDataModelProcessor.cs # Property/Methoden-Verarbeitung │ ├── PlaceholderValueRaplacer.cs # Platzhalter-Ersetzung │ ├── ReplacementActionCollection.cs # Typ-spezifische Actions @@ -78,12 +77,12 @@ MbSoftLab.TemplateEngine.Core/ │ ├── TemplateEngineConfig.cs # Konfigurations-Implementierung │ ├── TemplateEngineExtensions.cs # Erweiterungsmethoden │ └── MbSoftLab.TemplateEngine.Core.csproj # Projekt-Datei -├── MbSoftLab.TemplateEngine.Core.Tests/ # Unit-Tests +├── MbSoftLab.TemplateEngine.Core.Tests/ # Unit-Tests (referenzieren bei Bedarf Razor-Projekt) │ ├── TemplateEngineUnitTest.cs │ ├── RazorTemplateEngineUnitTest.cs │ ├── TemplateDataModelDummy.cs # Test-Fixtures │ └── *.cs # Weitere Test-Dateien -├── MbSoftlab.TemplateEngine.Core.Demo/ # Demo-Anwendung +├── MbSoftlab.TemplateEngine.Core.Demo/ # Demo-Anwendung (Razor-Demo referenziert Razor-Projekt) │ ├── Program.cs │ ├── Person.cs │ ├── Address.cs @@ -97,7 +96,10 @@ MbSoftLab.TemplateEngine.Core/ ├── CHANGELOG.md # Versions-Historie ├── RELEASENOTES.md # Release-Informationen ├── README.md # Haupt-Dokumentation -└── MbSoftLab.TemplateEngine.Core.sln # Solution-Datei +├── MbSoftLab.TemplateEngine.Core.Razor/ # Optionales Razor-Erweiterungsprojekt +│ ├── RazorTemplateEngine.cs # Razor-basierte Engine +│ └── MbSoftLab.TemplateEngine.Core.Razor.csproj +└── MbSoftLab.TemplateEngine.Core.sln # Solution-Datei (enthält beide Projekte) ``` --- @@ -119,6 +121,20 @@ dotnet pack --configuration Release **Output:** Das NuGet-Package wird in `bin/Release/` erstellt. +### Razor-Erweiterung (optional) + +Das Razor-Feature ist als separates Paket/Projekt verfügbar. + +```bash +# Razor-Erweiterung lokal referenzieren +dotnet add .csproj reference MbSoftLab.TemplateEngine.Core.Razor/MbSoftLab.TemplateEngine.Core.Razor.csproj + +# Oder als NuGet installieren +dotnet add package MbSoftLab.TemplateEngine.Core.Razor +``` + +Die Projekte, die `RazorTemplateEngine` verwenden, müssen die Razor-Erweiterung referenzieren oder das NuGet einsetzen. + ### Tests ausführen ```bash diff --git a/docs/examples.md b/docs/examples.md index 61389dd..4f6fa63 100644 --- a/docs/examples.md +++ b/docs/examples.md @@ -28,6 +28,12 @@ Install-Package MbSoftLab.TemplateEngine.Core dotnet add package MbSoftLab.TemplateEngine.Core ``` +Optional: Razor-Unterstützung + +```bash +dotnet add package MbSoftLab.TemplateEngine.Core.Razor +``` + ### Erstes Beispiel (30 Sekunden) ```csharp @@ -342,12 +348,13 @@ string result = engine.CreateStringFromTemplate(); --- -## Razor-Templates +## Razor-Templates (optional) ### Beispiel 12: Einfaches Razor-Template ```csharp using MbSoftLab.TemplateEngine.Core; +// Hinweis: Stellen Sie sicher, dass das Paket MbSoftLab.TemplateEngine.Core.Razor installiert ist. public class Person : TemplateDataModel { @@ -363,6 +370,7 @@ var person = new Person Age = 35 }; +// Razor steht erst nach Installation von MbSoftLab.TemplateEngine.Core.Razor zur Verfügung var engine = new RazorTemplateEngine(); string razorTemplate = @"