diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 668fe38..e7e59ad 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -45,7 +45,7 @@ jobs: SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} shell: powershell run: | - .\.sonar\scanner\dotnet-sonarscanner begin /k:"WickedFlame_Yaml" /o:"wickedflame" /d:sonar.login="${{ secrets.SONAR_TOKEN }}" /d:sonar.host.url="https://sonarcloud.io" /d:sonar.cs.opencover.reportsPaths="src/Tests/YamlMap.Tests/coverage.opencover.xml" + .\.sonar\scanner\dotnet-sonarscanner begin /k:"WickedFlame_Yaml" /o:"wickedflame" /d:sonar.login="${{ secrets.SONAR_TOKEN }}" /d:sonar.host.url="https://sonarcloud.io" /d:sonar.cs.opencover.reportsPaths="src/Tests/YamlMap.Tests/coverage.*.opencover.xml" dotnet build dotnet test /p:CollectCoverage=true /p:CoverletOutputFormat=opencover .\.sonar\scanner\dotnet-sonarscanner end /d:sonar.login="${{ secrets.SONAR_TOKEN }}" diff --git a/.gitignore b/.gitignore index 3e759b7..a638aa2 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ *.user *.userosscache *.sln.docstates +*.lutconfig # User-specific files (MonoDevelop/Xamarin Studio) *.userprefs diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..fddbce3 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,25 @@ +# Change Log +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](http://keepachangelog.com/) +and this project adheres to [Semantic Versioning](http://semver.org/). + +## [Unreleased] - yyyy-mm-dd + +### Added +- Create instances of types with parameterless constructors +- Added Benchmarks to ensure performance + +### Changed + +### Fixed + +## [1.2.3] - 2022-08-15 + +### Added + +### Changed +- Downgrade to netstandard2.0 instead of netstandard2.1 +- Update building to use [https://nuke.build/](https://nuke.build/) + +### Fixed \ No newline at end of file diff --git a/README.md b/README.md index 96e4331..6a108c2 100644 --- a/README.md +++ b/README.md @@ -120,3 +120,8 @@ WrappedText: > ``` +# Best practice +## Deserialing to Object +To deserialize a Yaml to a object, it is best to have a parameterless constructor. +If a object needs to have a constructor with parameters, the parameter names have to be the same as the properties that they are mapped to. +Else YamlMap will not be able to mapt the correct values to the parameters. diff --git a/YamlMap.sln b/YamlMap.sln index 937f238..0bb2660 100644 --- a/YamlMap.sln +++ b/YamlMap.sln @@ -12,6 +12,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution .travis.yml = .travis.yml appveyor.yml = appveyor.yml .github\workflows\build.yml = .github\workflows\build.yml + CHANGELOG.md = CHANGELOG.md LICENSE = LICENSE .github\workflows\linux.yml = .github\workflows\linux.yml README.md = README.md @@ -22,6 +23,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{61A95099 EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "_build", "build\_build.csproj", "{720AA512-BFE2-4345-A1ED-2D3B2D91F4B2}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "YamlMap.Benchmark", "src\Tests\YamlMap.Benchmark\YamlMap.Benchmark.csproj", "{7FFE3802-EDF9-4764-8259-BD0B9142C9FD}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -38,6 +41,10 @@ Global {4FF32EEA-66F0-4A99-8D95-7D1E5A6E0CF4}.Release|Any CPU.Build.0 = Release|Any CPU {720AA512-BFE2-4345-A1ED-2D3B2D91F4B2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {720AA512-BFE2-4345-A1ED-2D3B2D91F4B2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7FFE3802-EDF9-4764-8259-BD0B9142C9FD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7FFE3802-EDF9-4764-8259-BD0B9142C9FD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7FFE3802-EDF9-4764-8259-BD0B9142C9FD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7FFE3802-EDF9-4764-8259-BD0B9142C9FD}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -45,6 +52,7 @@ Global GlobalSection(NestedProjects) = preSolution {4FF32EEA-66F0-4A99-8D95-7D1E5A6E0CF4} = {61A95099-5D81-4BE8-AFA3-C1779E02A7AF} {720AA512-BFE2-4345-A1ED-2D3B2D91F4B2} = {B215E0CA-21DD-453C-89E7-D39337E6215D} + {7FFE3802-EDF9-4764-8259-BD0B9142C9FD} = {61A95099-5D81-4BE8-AFA3-C1779E02A7AF} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {FAEBE709-29D8-48BA-91F8-ABF8E2471FAD} diff --git a/appveyor.yml b/appveyor.yml index 1a639e8..c85ec8c 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,7 +1,7 @@ # http://www.appveyor.com/docs/appveyor-yml environment: - base_version: 1.2.3 + base_version: 1.2.4 version: $(base_version).{build} diff --git a/build/Build.cs b/build/Build.cs index 95cf87d..b7b628d 100644 --- a/build/Build.cs +++ b/build/Build.cs @@ -14,7 +14,6 @@ using static Nuke.Common.IO.PathConstruction; using static Nuke.Common.Tools.DotNet.DotNetTasks; -[CheckBuildProjectConfigurations] [ShutdownDotNetAfterServerBuild] class Build : NukeBuild { @@ -39,7 +38,7 @@ class Build : NukeBuild AbsolutePath TestsDirectory => RootDirectory / "Tests"; [Parameter("Version to be injected in the Build")] - public string Version { get; set; } = $"1.2.3"; + public string Version { get; set; } = $"1.2.4"; [Parameter("The Buildnumber provided by the CI")] public string BuildNo = "2"; diff --git a/src/Tests/YamlMap.Benchmark/Program.cs b/src/Tests/YamlMap.Benchmark/Program.cs new file mode 100644 index 0000000..d68daa7 --- /dev/null +++ b/src/Tests/YamlMap.Benchmark/Program.cs @@ -0,0 +1,38 @@ +// See https://aka.ms/new-console-template for more information + +using MeasureMap; +using System.Text; +using YamlMap; +using YamlMap.Benchmark; + +var value = new StringBuilder().AppendLine("Simple: root") + .AppendLine("StringList:") + .AppendLine(" - one") + .AppendLine(" - 2") + .AppendLine("ObjList:") + .AppendLine(" - Simple: simple") + .AppendLine(" - Child:") + .AppendLine(" Simple: child").ToString(); + + +ProfilerSession.StartSession() + .SetIterations(10) + .SetThreads(10) + .Task(c => + { + var reader = new YamlReader(); + reader.Read(value); + }) + .RunSession() + .Trace(); + + +//ProfilerSession.StartSession() +// .SetIterations(10) +// .Task(c => +// { +// var reader = new YamlReader(); +// reader.Read(value); +// }) +// .RunSession() +// .Trace(); \ No newline at end of file diff --git a/src/Tests/YamlMap.Benchmark/Results.md b/src/Tests/YamlMap.Benchmark/Results.md new file mode 100644 index 0000000..06c2dee --- /dev/null +++ b/src/Tests/YamlMap.Benchmark/Results.md @@ -0,0 +1,67 @@ + + + +# MeasureMap - v1.2.4 +## Summary +| Category | Metric | Value | +| --- | --- | ---: | +| Warmup | Duration Warmup | 00:00:00.0850161 | +| Setup | Threads | 10 | +| | Iterations | 100 | +| Duration | Duration | 00:00:00.2859164 | +| | Total Time | 00:00:00.5425069 | +| | Average Time | 00:00:00.0054250 | +| | Average Milliseconds | 5.425 ms | +| | Throughput | 349.75259/s | +| | Fastest | 00:00:00.0003884 | +| | Slowest | 00:00:00.0147817 | +| Memory | Memory Initial size | 128336 | +| | Memory End size | 185048 | +| | Memory Increase | 56712 | + +## Details per Thread +| ThreadId | Iterations | Average Time | Slowest | Fastest | Throughput | +| --- | --- | ---: | ---: | ---: | ---: | +| 4 | 10 | 00:00:00.0058555 | 00:00:00.0140982 | 00:00:00.0014117 | 170.77873/s | +| 5 | 10 | 00:00:00.0057905 | 00:00:00.0139230 | 00:00:00.0018329 | 172.69606/s | +| 6 | 10 | 00:00:00.0038066 | 00:00:00.0065659 | 00:00:00.0012217 | 262.69886/s | +| 7 | 10 | 00:00:00.0057911 | 00:00:00.0120258 | 00:00:00.0013858 | 172.67787/s | +| 8 | 10 | 00:00:00.0062313 | 00:00:00.0130830 | 00:00:00.0038898 | 160.47887/s | +| 9 | 10 | 00:00:00.0047726 | 00:00:00.0075059 | 00:00:00.0003884 | 209.5272/s | +| 10 | 10 | 00:00:00.0045559 | 00:00:00.0072848 | 00:00:00.0005383 | 219.49271/s | +| 11 | 10 | 00:00:00.0057704 | 00:00:00.0147817 | 00:00:00.0017698 | 173.29731/s | +| 12 | 10 | 00:00:00.0047492 | 00:00:00.0073229 | 00:00:00.0011710 | 210.56178/s | +| 13 | 10 | 00:00:00.0069272 | 00:00:00.0093442 | 00:00:00.0043829 | 144.3568/s | + + +# MeasureMap - v1.2.3 +## Summary +| Category | Metric | Value | +| --- | --- | ---: | +| Warmup | Duration Warmup | 00:00:00.0934861 | +| Setup | Threads | 10 | +| | Iterations | 100 | +| Duration | Duration | 00:00:00.3045892 | +| | Total Time | 00:00:00.5476232 | +| | Average Time | 00:00:00.0054762 | +| | Average Milliseconds | 5.4762 ms | +| | Throughput | 328.31105/s | +| | Fastest | 00:00:00.0000867 | +| | Slowest | 00:00:00.0143229 | +| Memory | Memory Initial size | 126288 | +| | Memory End size | 198552 | +| | Memory Increase | 72264 | + +## Details per Thread +| ThreadId | Iterations | Average Time | Slowest | Fastest | Throughput | +| --- | --- | ---: | ---: | ---: | ---: | +| 4 | 10 | 00:00:00.0071977 | 00:00:00.0141091 | 00:00:00.0026345 | 138.93231/s | +| 5 | 10 | 00:00:00.0051405 | 00:00:00.0098962 | 00:00:00.0001348 | 194.53058/s | +| 6 | 10 | 00:00:00.0051938 | 00:00:00.0099995 | 00:00:00.0014394 | 192.53689/s | +| 7 | 10 | 00:00:00.0042084 | 00:00:00.0087129 | 00:00:00.0004524 | 237.61774/s | +| 8 | 10 | 00:00:00.0064520 | 00:00:00.0143229 | 00:00:00.0000867 | 154.98926/s | +| 9 | 10 | 00:00:00.0054007 | 00:00:00.0104453 | 00:00:00.0029130 | 185.15981/s | +| 10 | 10 | 00:00:00.0051964 | 00:00:00.0071006 | 00:00:00.0030690 | 192.44092/s | +| 11 | 10 | 00:00:00.0051198 | 00:00:00.0076924 | 00:00:00.0023300 | 195.3186/s | +| 12 | 10 | 00:00:00.0051012 | 00:00:00.0089473 | 00:00:00.0002999 | 196.03077/s | +| 13 | 10 | 00:00:00.0057514 | 00:00:00.0104961 | 00:00:00.0001130 | 173.8689/s | \ No newline at end of file diff --git a/src/Tests/YamlMap.Benchmark/TestItem.cs b/src/Tests/YamlMap.Benchmark/TestItem.cs new file mode 100644 index 0000000..93444e7 --- /dev/null +++ b/src/Tests/YamlMap.Benchmark/TestItem.cs @@ -0,0 +1,25 @@ + +namespace YamlMap.Benchmark +{ + public class TestlItem + { + public string Simple { get; set; } + + public TestlItemChild Child { get; set; } + + public IEnumerable StringList { get; set; } + + public IEnumerable ObjList { get; set; } + } + + public class TestlItemChild + { + public string Simple { get; set; } + + public TestlItem Child { get; set; } + + public IEnumerable StringList { get; set; } + + public IEnumerable ObjList { get; set; } + } +} diff --git a/src/Tests/YamlMap.Benchmark/YamlMap.Benchmark.csproj b/src/Tests/YamlMap.Benchmark/YamlMap.Benchmark.csproj new file mode 100644 index 0000000..cb37782 --- /dev/null +++ b/src/Tests/YamlMap.Benchmark/YamlMap.Benchmark.csproj @@ -0,0 +1,18 @@ + + + + Exe + net6.0 + enable + enable + + + + + + + + + + + diff --git a/src/Tests/YamlMap.Tests/Reader/YamlReaderArrayTests.cs b/src/Tests/YamlMap.Tests/Reader/YamlReaderArrayTests.cs index 80fcd53..6565863 100644 --- a/src/Tests/YamlMap.Tests/Reader/YamlReaderArrayTests.cs +++ b/src/Tests/YamlMap.Tests/Reader/YamlReaderArrayTests.cs @@ -9,7 +9,7 @@ namespace YamlMap.Tests.Reader public class YamlReaderArrayTests { [Test] - public void WickedFlame_Yaml_YamlReader_Array() + public void YamlMap_YamlReader_Array() { var lines = new[] { @@ -31,7 +31,7 @@ public void WickedFlame_Yaml_YamlReader_Array() } [Test] - public void WickedFlame_Yaml_YamlReader_Array_Brackets() + public void YamlMap_YamlReader_Array_Brackets() { var lines = new[] { @@ -48,7 +48,7 @@ public void WickedFlame_Yaml_YamlReader_Array_Brackets() } [Test] - public void WickedFlame_Yaml_YamlReader_Array_Object() + public void YamlMap_YamlReader_Array_Object() { var lines = new[] { @@ -68,7 +68,7 @@ public void WickedFlame_Yaml_YamlReader_Array_Object() } [Test] - public void WickedFlame_Yaml_YamlReader_Array_Nested() + public void YamlMap_YamlReader_Array_Nested() { var lines = new[] { diff --git a/src/Tests/YamlMap.Tests/Reader/YamlReaderDictionaryTests.cs b/src/Tests/YamlMap.Tests/Reader/YamlReaderDictionaryTests.cs index 6f8089c..1dc39e8 100644 --- a/src/Tests/YamlMap.Tests/Reader/YamlReaderDictionaryTests.cs +++ b/src/Tests/YamlMap.Tests/Reader/YamlReaderDictionaryTests.cs @@ -10,7 +10,7 @@ namespace YamlMap.Tests.Reader public class YamlReaderDictionaryTests { [Test] - public void WickedFlame_Yaml_YamlReader_Dictionary() + public void YamlMap_YamlReader_Dictionary() { var lines = new[] { @@ -28,7 +28,7 @@ public void WickedFlame_Yaml_YamlReader_Dictionary() } [Test] - public void WickedFlame_Yaml_YamlReader_Dictionary_Interface() + public void YamlMap_YamlReader_Dictionary_Interface() { var lines = new[] { @@ -46,7 +46,7 @@ public void WickedFlame_Yaml_YamlReader_Dictionary_Interface() } [Test] - public void WickedFlame_Yaml_YamlReader_Dictionary_List() + public void YamlMap_YamlReader_Dictionary_List() { // this is a list of object instead of a dictionary // to use dictionary remove the - @@ -62,7 +62,7 @@ public void WickedFlame_Yaml_YamlReader_Dictionary_List() } [Test] - public void WickedFlame_Yaml_YamlReader_Dictionary_Objects() + public void YamlMap_YamlReader_Dictionary_Objects() { var lines = new[] { diff --git a/src/Tests/YamlMap.Tests/Reader/YamlReaderListTests.cs b/src/Tests/YamlMap.Tests/Reader/YamlReaderListTests.cs index d5bb4a9..862f49f 100644 --- a/src/Tests/YamlMap.Tests/Reader/YamlReaderListTests.cs +++ b/src/Tests/YamlMap.Tests/Reader/YamlReaderListTests.cs @@ -10,7 +10,7 @@ namespace YamlMap.Tests.Reader public class YamlReaderListTests { [Test] - public void WickedFlame_Yaml_YamlReader_List() + public void YamlMap_YamlReader_List() { var lines = new[] { @@ -28,7 +28,7 @@ public void WickedFlame_Yaml_YamlReader_List() } [Test] - public void WickedFlame_Yaml_YamlReader_List_Interface() + public void YamlMap_YamlReader_List_Interface() { var lines = new[] { @@ -46,7 +46,7 @@ public void WickedFlame_Yaml_YamlReader_List_Interface() } [Test] - public void WickedFlame_Yaml_YamlReader_List_IEnumerable() + public void YamlMap_YamlReader_List_IEnumerable() { var lines = new[] { diff --git a/src/Tests/YamlMap.Tests/Serialization/ArrayInstanceFactoryTests.cs b/src/Tests/YamlMap.Tests/Serialization/ArrayInstanceFactoryTests.cs new file mode 100644 index 0000000..1c1148f --- /dev/null +++ b/src/Tests/YamlMap.Tests/Serialization/ArrayInstanceFactoryTests.cs @@ -0,0 +1,28 @@ +using FluentAssertions; +using NUnit.Framework; +using YamlMap.Serialization; + +namespace YamlMap.Tests.Serialization +{ + public class ArrayInstanceFactoryTests + { + [Test] + public void ArrayInstanceFactory_Type() + { + var token = new Token("", 0); + token.Set(new ValueToken("Value", "1", 0)); + + ArrayInstanceFactory.Factory.CreateInstance(typeof(int[]), token).Invoke().Should().BeAssignableTo(); + } + + [Test] + public void ArrayInstanceFactory_Length() + { + var token = new Token("", 0); + token.Set(new ValueToken("Value1", "1", 0)); + token.Set(new ValueToken("Value2", "2", 0)); + + ((int[][])ArrayInstanceFactory.Factory.CreateInstance(typeof(int[]), token).Invoke()).Should().HaveCount(2); + } + } +} diff --git a/src/Tests/YamlMap.Tests/Serialization/ConstructorResolverTests.cs b/src/Tests/YamlMap.Tests/Serialization/ConstructorResolverTests.cs new file mode 100644 index 0000000..5c88914 --- /dev/null +++ b/src/Tests/YamlMap.Tests/Serialization/ConstructorResolverTests.cs @@ -0,0 +1,97 @@ +using System; +using FluentAssertions; +using NUnit.Framework; +using Polaroider; +using YamlMap.Serialization; + +namespace YamlMap.Tests.Serialization +{ + public class ConstructorResolverTests + { + [Test] + public void ConstructorResolver_NoCtor() + { + var resolver = new ContractResolver(); + var contract = resolver.GetConstructor(typeof(NoCtor)); + + contract.Constructor.GetParameters().Should().HaveCount(0); + } + + [Test] + public void ConstructorResolver_WithCtor() + { + var resolver = new ContractResolver(); + var contract = resolver.GetConstructor(typeof(WithCtor)); + + contract.Constructor.GetParameters().Should().HaveCount(2); + } + + [Test] + public void ConstructorResolver_CreateConstructoParameters() + { + var tokens = new[] + { + new ValueToken("test", "fail", 0), + new ValueToken("Id", "1", 0), + new ValueToken("Value", "passed", 0), + new ValueToken("values", "fail", 0) + }; + var resolver = new ContractResolver(); + var contract = resolver.GetConstructor(typeof(WithCtor)); + + resolver.CreateConstructoParameters(contract.Constructor, tokens).MatchSnapshot(); + } + + [Test] + public void ConstructorResolver_CreateConstructoParameters_InvalidType() + { + var tokens = new[] + { + new ValueToken("Id", "fail", 0), + new ValueToken("Value", "passed", 0) + }; + var resolver = new ContractResolver(); + var contract = resolver.GetConstructor(typeof(WithCtor)); + + resolver.CreateConstructoParameters(contract.Constructor, tokens).Should().HaveCount(1); + } + + [Test] + public void ConstructorResolver_CreateConstructoParameters_Primitive() + { + var tokens = new[] + { + new ValueToken("Value", "5", 0) + }; + var resolver = new ContractResolver(); + var contract = resolver.GetConstructor(typeof(int)); + + resolver.CreateConstructoParameters(contract.Constructor, tokens).Should().HaveCount(0); + } + } + + public class NoCtor + { + public int Id { get; set; } + + public string Value { get; set; } + } + + public class WithCtor + { + public WithCtor(int id) + { + Id = id; + } + + public WithCtor(string value, int id) + { + Value = value; + Id = id; + } + + public int Id { get; set; } + + public string Value { get; set; } + } +} diff --git a/src/Tests/YamlMap.Tests/Serialization/InstanceFactoryTests.cs b/src/Tests/YamlMap.Tests/Serialization/InstanceFactoryTests.cs new file mode 100644 index 0000000..16187c6 --- /dev/null +++ b/src/Tests/YamlMap.Tests/Serialization/InstanceFactoryTests.cs @@ -0,0 +1,68 @@ +using NUnit.Framework; +using System; +using FluentAssertions; +using YamlMap.Serialization; + +namespace YamlMap.Tests.Serialization +{ + public class InstanceFactoryTests + { + [Test] + public void InstanceFactory_Create_Simple() + { + var token = new Token("", 0); + token.Set(new ValueToken("Id", "1", 0)); + token.Set(new ValueToken("Value", "passed", 0)); + + var factory = new InstanceFactory(); + var obj = factory.CreateInstance(typeof(NoCtor), token); + + obj.Invoke().Should().NotBeNull(); + } + + [Test] + public void InstanceFactory_Create_ConstructorParameters() + { + var token = new Token("", 0); + token.Set(new ValueToken("Id", "1", 0)); + token.Set(new ValueToken("Value", "passed", 0)); + + var factory = new InstanceFactory(); + var obj = factory.CreateInstance(typeof(WithCtor), token); + + obj.Invoke().Should().NotBeNull(); + } + + [Test] + public void InstanceFactory_Create_ConstructorParameters_DefaultFactory() + { + var token = new Token("", 0); + token.Set(new ValueToken("Id", "1", 0)); + token.Set(new ValueToken("Value", "passed", 0)); + + InstanceFactory.Factory.CreateInstance(typeof(WithCtor), token).Invoke().Should().NotBeNull(); + } + + [Test] + public void InstanceFactory_Create_InvalidParameters() + { + var token = new Token("", 0); + token.Set(new ValueToken("Id", "fail", 0)); + token.Set(new ValueToken("Value", "passed", 0)); + + var factory = new InstanceFactory(); + var obj = factory.CreateInstance(typeof(WithCtor), token); + + obj.Should().Throw(); + } + + [Test] + public void InstanceFactory_Create_PrimitiveType() + { + var token = new Token("", 0); + token.Set(new ValueToken("Value", "1", 0)); + + InstanceFactory.Factory.CreateInstance(typeof(int), token).Invoke().Should().Be(0); + } + } +} diff --git a/src/Tests/YamlMap.Tests/Serialization/Mappers/ArrayMapperTests.cs b/src/Tests/YamlMap.Tests/Serialization/Mappers/ArrayMapperTests.cs index 9e8160a..0102449 100644 --- a/src/Tests/YamlMap.Tests/Serialization/Mappers/ArrayMapperTests.cs +++ b/src/Tests/YamlMap.Tests/Serialization/Mappers/ArrayMapperTests.cs @@ -11,7 +11,7 @@ namespace YamlMap.Tests.Serialization.Mappers public class ArrayMapperTests { [Test] - public void WickedFlame_Yaml_Serialization_ArrayMapper_Simple() + public void YamlMap_Serialization_ArrayMapper_Simple() { var token = new ValueToken("Key", "Value", 0); var list = new string[1]; @@ -24,7 +24,7 @@ public void WickedFlame_Yaml_Serialization_ArrayMapper_Simple() } [Test] - public void WickedFlame_Yaml_Serialization_ArrayMapper() + public void YamlMap_Serialization_ArrayMapper() { var token = new Token("tmp", 0); diff --git a/src/Tests/YamlMap.Tests/Serialization/Mappers/GenericDictionaryMapperTests.cs b/src/Tests/YamlMap.Tests/Serialization/Mappers/GenericDictionaryMapperTests.cs index 799a039..7c007db 100644 --- a/src/Tests/YamlMap.Tests/Serialization/Mappers/GenericDictionaryMapperTests.cs +++ b/src/Tests/YamlMap.Tests/Serialization/Mappers/GenericDictionaryMapperTests.cs @@ -11,7 +11,7 @@ namespace YamlMap.Tests.Serialization.Mappers public class GenericDictionaryMapperTests { [Test] - public void WickedFlame_Yaml_Serialization_GenericDictionaryMapper_Simple() + public void YamlMap_Serialization_GenericDictionaryMapper_Simple() { var token = new ValueToken("Key", "Value", 0); var list = new Dictionary(); @@ -24,7 +24,7 @@ public void WickedFlame_Yaml_Serialization_GenericDictionaryMapper_Simple() } [Test] - public void WickedFlame_Yaml_Serialization_GenericDictionaryMapper() + public void YamlMap_Serialization_GenericDictionaryMapper() { var token = new Token("Key", 0); @@ -40,7 +40,7 @@ public void WickedFlame_Yaml_Serialization_GenericDictionaryMapper() } [Test] - public void WickedFlame_Yaml_Serialization_GenericDictionaryMapper_NoDictionary() + public void YamlMap_Serialization_GenericDictionaryMapper_NoDictionary() { var token = new Token("Key", 0); diff --git a/src/Tests/YamlMap.Tests/Serialization/Mappers/GenericListMapperTests.cs b/src/Tests/YamlMap.Tests/Serialization/Mappers/GenericListMapperTests.cs index b12337e..a7d441f 100644 --- a/src/Tests/YamlMap.Tests/Serialization/Mappers/GenericListMapperTests.cs +++ b/src/Tests/YamlMap.Tests/Serialization/Mappers/GenericListMapperTests.cs @@ -11,7 +11,7 @@ namespace YamlMap.Tests.Serialization.Mappers public class GenericListMapperTests { [Test] - public void WickedFlame_Yaml_Serialization_GenericListMapper_Simple() + public void YamlMap_Serialization_GenericListMapper_Simple() { var token = new ValueToken("Key", "Value", 0); var list = new List(); @@ -24,7 +24,7 @@ public void WickedFlame_Yaml_Serialization_GenericListMapper_Simple() } [Test] - public void WickedFlame_Yaml_Serialization_GenericListMapper() + public void YamlMap_Serialization_GenericListMapper() { var token = new Token("Key", 0); @@ -40,7 +40,7 @@ public void WickedFlame_Yaml_Serialization_GenericListMapper() } [Test] - public void WickedFlame_Yaml_Serialization_GenericListMapper_NoList() + public void YamlMap_Serialization_GenericListMapper_NoList() { var token = new Token("Key", 0); diff --git a/src/Tests/YamlMap.Tests/Serialization/Mappers/MapperFactoryTests.cs b/src/Tests/YamlMap.Tests/Serialization/Mappers/MapperFactoryTests.cs index 0ecfb9d..18a7405 100644 --- a/src/Tests/YamlMap.Tests/Serialization/Mappers/MapperFactoryTests.cs +++ b/src/Tests/YamlMap.Tests/Serialization/Mappers/MapperFactoryTests.cs @@ -12,35 +12,35 @@ namespace YamlMap.Tests.Serialization.Mappers public class MapperFactoryTests { [Test] - public void WickedFlame_Yaml_Serialization_MapperFactory_List() + public void YamlMap_Serialization_MapperFactory_List() { var mapper = MapperFactory.GetObjectMapper(new List(), typeof(MapperItem)); Assert.IsInstanceOf(mapper); } [Test] - public void WickedFlame_Yaml_Serialization_MapperFactory_Dictionary() + public void YamlMap_Serialization_MapperFactory_Dictionary() { var mapper = MapperFactory.GetObjectMapper(new Dictionary(), typeof(MapperItem)); Assert.IsInstanceOf(mapper); } [Test] - public void WickedFlame_Yaml_Serialization_MapperFactory_Array() + public void YamlMap_Serialization_MapperFactory_Array() { var mapper = MapperFactory.GetObjectMapper(new string[] {}, typeof(MapperItem)); Assert.IsInstanceOf(mapper); } [Test] - public void WickedFlame_Yaml_Serialization_MapperFactory_Array2() + public void YamlMap_Serialization_MapperFactory_Array2() { var mapper = MapperFactory.GetObjectMapper(new ArrayList(), typeof(IList)); Assert.IsInstanceOf(mapper); } [Test] - public void WickedFlame_Yaml_Serialization_MapperFactory_Default() + public void YamlMap_Serialization_MapperFactory_Default() { var mapper = MapperFactory.GetObjectMapper(new MapperItem(), typeof(MapperItem)); Assert.IsInstanceOf(mapper); diff --git a/src/Tests/YamlMap.Tests/Serialization/ObjectFactoryTests.cs b/src/Tests/YamlMap.Tests/Serialization/ObjectBuilderTests.cs similarity index 62% rename from src/Tests/YamlMap.Tests/Serialization/ObjectFactoryTests.cs rename to src/Tests/YamlMap.Tests/Serialization/ObjectBuilderTests.cs index 13e4c5e..274d80b 100644 --- a/src/Tests/YamlMap.Tests/Serialization/ObjectFactoryTests.cs +++ b/src/Tests/YamlMap.Tests/Serialization/ObjectBuilderTests.cs @@ -2,13 +2,15 @@ using System.Collections; using System.Collections.Generic; using System.Text; +using FluentAssertions; using NUnit.Framework; using YamlMap.Serialization; +using static YamlMap.Tests.Serialization.ObjectBuilderTests; namespace YamlMap.Tests.Serialization { [TestFixture] - public class ObjectFactoryTests + public class ObjectBuilderTests { [TestCase(typeof(IEnumerable), typeof(List))] [TestCase(typeof(IEnumerable), typeof(List))] @@ -18,7 +20,7 @@ public class ObjectFactoryTests [TestCase(typeof(ICollection), typeof(List))] [TestCase(typeof(IDictionary), typeof(Dictionary))] [TestCase(typeof(IDictionary), typeof(Dictionary))] - public void WickedFlame_Yaml_Serialization_ObjectFactory_GenericLists(Type input, Type expected) + public void ObjectBuilder_GenericLists(Type input, Type expected) { var token = new Token("test", 0); var obj = input.CreateInstance(token); @@ -30,7 +32,7 @@ public void WickedFlame_Yaml_Serialization_ObjectFactory_GenericLists(Type input [TestCase(typeof(IList), typeof(List))] [TestCase(typeof(ICollection), typeof(List))] [TestCase(typeof(IDictionary), typeof(Dictionary))] - public void WickedFlame_Yaml_Serialization_ObjectFactory_NonGenericLists(Type input, Type expected) + public void ObjectBuilder_NonGenericLists(Type input, Type expected) { var token = new Token("test", 0); var obj = input.CreateInstance(token); @@ -39,7 +41,7 @@ public void WickedFlame_Yaml_Serialization_ObjectFactory_NonGenericLists(Type in } [TestCase(typeof(TestObject), typeof(TestObject))] - public void WickedFlame_Yaml_Serialization_ObjectFactory_BasicObject(Type input, Type expected) + public void ObjectBuilder_BasicObject(Type input, Type expected) { var token = new Token("test", 0); var obj = input.CreateInstance(token); @@ -48,7 +50,7 @@ public void WickedFlame_Yaml_Serialization_ObjectFactory_BasicObject(Type input, } [Test] - public void WickedFlame_Yaml_Serialization_ObjectFactory_Array() + public void ObjectBuilder_Array() { var type = typeof(string[]); var token = new Token("test", 0); @@ -62,6 +64,35 @@ public void WickedFlame_Yaml_Serialization_ObjectFactory_Array() Assert.AreEqual(3, ((IList) obj).Count); } + [Test] + public void ObjectBuilder_Generics() + { + var type = typeof(GenericTest); + var token = new Token("test", 1); + + var obj = type.CreateInstance(token); + + obj.Should().NotBeNull(); + obj.Should().BeAssignableTo>(); + } + + [Test] + public void ObjectBuilder_GenericTypeDefinition() + { + var type = typeof(GenericTest<>); + var token = new Token("test", 1); + + var obj = type.CreateInstance(token); + + obj.Should().NotBeNull(); + obj.Should().BeAssignableTo>(); + } + public class TestObject { } + + public class GenericTest + { + public int Test { get; set; } + } } } diff --git a/src/Tests/YamlMap.Tests/Serialization/_Snapshots/ConstructorResolverTests_ConstructorResolver_CreateConstructoParameters.snapshot b/src/Tests/YamlMap.Tests/Serialization/_Snapshots/ConstructorResolverTests_ConstructorResolver_CreateConstructoParameters.snapshot new file mode 100644 index 0000000..ae0f2a3 --- /dev/null +++ b/src/Tests/YamlMap.Tests/Serialization/_Snapshots/ConstructorResolverTests_ConstructorResolver_CreateConstructoParameters.snapshot @@ -0,0 +1,3 @@ +---data +passed +1 diff --git a/src/Tests/YamlMap.Tests/YamlFileReaderTests.cs b/src/Tests/YamlMap.Tests/YamlFileReaderTests.cs index 50c894e..088c4b5 100644 --- a/src/Tests/YamlMap.Tests/YamlFileReaderTests.cs +++ b/src/Tests/YamlMap.Tests/YamlFileReaderTests.cs @@ -11,7 +11,7 @@ namespace YamlMap.Tests public class YamlFileReaderTests { [Test] - public void WickedFlame_Yaml_YamlReader_SimpleProperty_Root() + public void YamlMap_YamlReader_SimpleProperty_Root() { var reader = new YamlFileReader(); var data = reader.Read("YamlTest.yml"); diff --git a/src/Tests/YamlMap.Tests/YamlMap.Tests.csproj b/src/Tests/YamlMap.Tests/YamlMap.Tests.csproj index 103da7d..14c605e 100644 --- a/src/Tests/YamlMap.Tests/YamlMap.Tests.csproj +++ b/src/Tests/YamlMap.Tests/YamlMap.Tests.csproj @@ -1,68 +1,70 @@  - - net6.0;net48 + + net6.0;net48 - false - + false + 9.0 + - - - - - - - - - - + + + + + + + + + + - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + - - - + + + - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + - - - Always - - + + + Always + + diff --git a/src/Tests/YamlMap.Tests/YamlReaderArrayElementsTests.cs b/src/Tests/YamlMap.Tests/YamlReaderArrayElementsTests.cs index 914ea4b..4bf2f3f 100644 --- a/src/Tests/YamlMap.Tests/YamlReaderArrayElementsTests.cs +++ b/src/Tests/YamlMap.Tests/YamlReaderArrayElementsTests.cs @@ -11,7 +11,7 @@ namespace YamlMap.Tests public class YamlReaderArrayElementsTests { [Test] - public void WickedFlame_Yaml_YamlReader_Array_SimpleProperty_Root() + public void YamlMap_YamlReader_Array_SimpleProperty_Root() { var lines = new[] { @@ -25,7 +25,7 @@ public void WickedFlame_Yaml_YamlReader_Array_SimpleProperty_Root() } [Test] - public void WickedFlame_Yaml_YamlReader_Array_ObjectProperty_Root() + public void YamlMap_YamlReader_Array_ObjectProperty_Root() { var lines = new[] { @@ -42,7 +42,7 @@ public void WickedFlame_Yaml_YamlReader_Array_ObjectProperty_Root() } [Test] - public void WickedFlame_Yaml_YamlReader_Array_ObjectProperty_Nested() + public void YamlMap_YamlReader_Array_ObjectProperty_Nested() { var lines = new[] { @@ -62,7 +62,7 @@ public void WickedFlame_Yaml_YamlReader_Array_ObjectProperty_Nested() } [Test] - public void WickedFlame_Yaml_YamlReader_Array_ObjectProperty_AfterNested() + public void YamlMap_YamlReader_Array_ObjectProperty_AfterNested() { var lines = new[] { @@ -80,7 +80,7 @@ public void WickedFlame_Yaml_YamlReader_Array_ObjectProperty_AfterNested() } [Test] - public void WickedFlame_Yaml_YamlReader_Array_StringList() + public void YamlMap_YamlReader_Array_StringList() { var lines = new[] { @@ -101,7 +101,7 @@ public void WickedFlame_Yaml_YamlReader_Array_StringList() } [Test] - public void WickedFlame_Yaml_YamlReader_Array_EnumerableList() + public void YamlMap_YamlReader_Array_EnumerableList() { var lines = new[] { @@ -122,7 +122,7 @@ public void WickedFlame_Yaml_YamlReader_Array_EnumerableList() } [Test] - public void WickedFlame_Yaml_YamlReader_Array_ObjectList() + public void YamlMap_YamlReader_Array_ObjectList() { var lines = new[] { @@ -143,7 +143,7 @@ public void WickedFlame_Yaml_YamlReader_Array_ObjectList() } [Test] - public void WickedFlame_Yaml_YamlReader_Array_NestedObjectList() + public void YamlMap_YamlReader_Array_NestedObjectList() { var lines = new[] { diff --git a/src/Tests/YamlMap.Tests/YamlWriterTests.cs b/src/Tests/YamlMap.Tests/YamlWriterTests.cs index 2483f1c..c3665cc 100644 --- a/src/Tests/YamlMap.Tests/YamlWriterTests.cs +++ b/src/Tests/YamlMap.Tests/YamlWriterTests.cs @@ -9,7 +9,7 @@ namespace YamlMap.Tests public class YamlWriterTests { [Test] - public void WickedFlame_Yaml_YamlWriter() + public void YamlMap_YamlWriter() { var item = new YamlItem { @@ -24,7 +24,7 @@ public void WickedFlame_Yaml_YamlWriter() //TODO: null property [Test] - public void WickedFlame_Yaml_YamlWriter_null() + public void YamlMap_YamlWriter_null() { var item = new YamlItem { @@ -39,7 +39,7 @@ public void WickedFlame_Yaml_YamlWriter_null() //TODO: protected/private property [Test] - public void WickedFlame_Yaml_YamlWriter_Child() + public void YamlMap_YamlWriter_Child() { var item = new YamlItem { @@ -62,7 +62,7 @@ public void WickedFlame_Yaml_YamlWriter_Child() } [Test] - public void WickedFlame_Yaml_YamlWriter_StringArry() + public void YamlMap_YamlWriter_StringArry() { var item = new YamlItem { @@ -83,7 +83,7 @@ public void WickedFlame_Yaml_YamlWriter_StringArry() } [Test] - public void WickedFlame_Yaml_YamlWriter_ObjectList() + public void YamlMap_YamlWriter_ObjectList() { var item = new YamlItem { @@ -109,7 +109,7 @@ public void WickedFlame_Yaml_YamlWriter_ObjectList() } [Test] - public void WickedFlame_Yaml_YamlWriter_String_SpecialChars() + public void YamlMap_YamlWriter_String_SpecialChars() { var reader = new YamlWriter(); var data = reader.Write(new { Value = "tes:one" }); @@ -123,7 +123,7 @@ public void WickedFlame_Yaml_YamlWriter_String_SpecialChars() } [Test] - public void WickedFlame_Yaml_YamlWriter_StringList_SpecialChars() + public void YamlMap_YamlWriter_StringList_SpecialChars() { var reader = new YamlWriter(); var data = reader.Write(new { Values = new[] @@ -143,7 +143,7 @@ public void WickedFlame_Yaml_YamlWriter_StringList_SpecialChars() } [Test] - public void WickedFlame_Yaml_YamlWriter_Type() + public void YamlMap_YamlWriter_Type() { var reader = new YamlWriter(); var data = reader.Write(new { Type = typeof(YamlWriter) }); diff --git a/src/YamlMap/Serialization/ArrayInstanceFactory.cs b/src/YamlMap/Serialization/ArrayInstanceFactory.cs new file mode 100644 index 0000000..fdf4c64 --- /dev/null +++ b/src/YamlMap/Serialization/ArrayInstanceFactory.cs @@ -0,0 +1,26 @@ +using System; + +namespace YamlMap.Serialization +{ + /// + /// Default factory to create instances of arrays + /// + public class ArrayInstanceFactory : IInstanceFactory + { + /// + /// Singleton instance of the factory + /// + public static IInstanceFactory Factory { get; } = new ArrayInstanceFactory(); + + /// + /// Create an instance of the type + /// + /// + /// + /// + public Func CreateInstance(Type type, IToken token) + { + return () => Array.CreateInstance(type, token.Count); + } + } +} diff --git a/src/YamlMap/Serialization/ContractResolver.cs b/src/YamlMap/Serialization/ContractResolver.cs new file mode 100644 index 0000000..6d085ab --- /dev/null +++ b/src/YamlMap/Serialization/ContractResolver.cs @@ -0,0 +1,115 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; + +namespace YamlMap.Serialization +{ + /// + /// Resolve from + /// + public class ContractResolver + { + /// + /// Extract the Constructor from a + /// + /// + /// + public ObjectContract GetConstructor(Type type) + { + var ctors = type.GetConstructors(BindingFlags.Instance | BindingFlags.Public) + .Select(c => + new + { + Constructor = c, + Parameters = c.GetParameters() + }) + .OrderBy(c => c.Parameters.Length) + .ToList(); + + if (!ctors.Any()) + { + return new ObjectContract + { + Type = type + }; + } + + if (ctors.Any(p => p.Parameters.Length == 0)) + { + return new ObjectContract + { + Type = type, + Constructor = ctors.First(p => p.Parameters.Length == 0).Constructor + }; + } + + return new ObjectContract + { + Type = type, + Constructor = ctors.Last().Constructor + }; + } + + /// + /// Try to create the parameters for a constructor based on the items in the + /// - Parameters have to be named the sames as the properties that they are assigned to + /// + /// + /// + /// + public object[] CreateConstructoParameters(ConstructorInfo ctor, IToken[] tokens) + { + if (ctor == null) + { + return Array.Empty(); + } + + var parameters = ctor.GetParameters(); + + var parameterCollection = new List(); + + foreach (var parameterInfo in parameters) + { + if (parameterInfo.Name == null) + { + continue; + } + + var token = MatchProperty(tokens, parameterInfo.Name); + + // ensure that property will have a name from matching property or from parameterinfo + // parameterinfo could have no name if generated by a proxy (I'm looking at you Castle) + if (token != null && parameterInfo.Name != null) + { + var converted = TypeConverter.Convert(parameterInfo.ParameterType, token.Value); + if (converted != null) + { + parameterCollection.Add(converted); + } + } + } + + return parameterCollection.ToArray(); + } + + private ValueToken MatchProperty(IEnumerable tokens, string name) + { + // it is possible to generate a member with a null name using Reflection.Emit + // protect against an ArgumentNullException from GetClosestMatchProperty by testing for null here + if (name == null) + { + return null; + } + + var token = tokens.Where(t => t.TokenType == TokenType.Value).FirstOrDefault(t => t.Key.Equals(name, StringComparison.OrdinalIgnoreCase)) as ValueToken; + // must match type as well as name + if (token == null) + { + return null; + } + + return token; + } + } +} diff --git a/src/YamlMap/Serialization/GenericTypeInstanceFactory.cs b/src/YamlMap/Serialization/GenericTypeInstanceFactory.cs new file mode 100644 index 0000000..162297e --- /dev/null +++ b/src/YamlMap/Serialization/GenericTypeInstanceFactory.cs @@ -0,0 +1,34 @@ +using System; + +namespace YamlMap.Serialization +{ + /// + /// Default factory to create instances of Generic Types + /// + public class GenericTypeInstanceFactory : IInstanceFactory + { + /// + /// Singleton instance of the factory + /// + public static IInstanceFactory Factory { get; } = new GenericTypeInstanceFactory(); + + /// + /// Create an instance of the type + /// + /// + /// + /// + public Func CreateInstance(Type type, IToken token) + { + var genericArgs = type.GetGenericArguments(); + var typeArgs = new Type[genericArgs.Length]; + for (var i = 0; i < genericArgs.Length; i++) + { + typeArgs[i] = typeof(object); + } + + var realizedType = type.MakeGenericType(typeArgs); + return () => realizedType.CreateInstance(token); + } + } +} diff --git a/src/YamlMap/Serialization/IInstanceFactory.cs b/src/YamlMap/Serialization/IInstanceFactory.cs new file mode 100644 index 0000000..ba57acc --- /dev/null +++ b/src/YamlMap/Serialization/IInstanceFactory.cs @@ -0,0 +1,18 @@ +using System; + +namespace YamlMap.Serialization +{ + /// + /// Interface to define a factory for creating instances of types + /// + public interface IInstanceFactory + { + /// + /// Create a instance of the type + /// + /// + /// + /// + Func CreateInstance(Type type, IToken token); + } +} diff --git a/src/YamlMap/Serialization/InstanceFactory.cs b/src/YamlMap/Serialization/InstanceFactory.cs new file mode 100644 index 0000000..43c3e3b --- /dev/null +++ b/src/YamlMap/Serialization/InstanceFactory.cs @@ -0,0 +1,40 @@ +using System; + +namespace YamlMap.Serialization +{ + /// + /// Default factory to create instances of objects + /// + public class InstanceFactory : IInstanceFactory + { + /// + /// Singleton instance of the factory + /// + public static IInstanceFactory Factory { get; } = new InstanceFactory(); + + /// + /// Create an instance of the type + /// + /// + /// + /// + public Func CreateInstance(Type type, IToken token) + { + var resolver = new ContractResolver(); + var contract = resolver.GetConstructor(type); + contract.Parameters = resolver.CreateConstructoParameters(contract.Constructor, token.GetChildTokens()); + + return () => CreateInstance(contract); + } + + private object CreateInstance(ObjectContract contract) + { + if (contract.Parameters != null && contract.Parameters.Length == 0) + { + return Activator.CreateInstance(contract.Type); + } + + return Activator.CreateInstance(contract.Type, contract.Parameters); + } + } +} diff --git a/src/YamlMap/Serialization/ObjectFactory.cs b/src/YamlMap/Serialization/ObjectBuilder.cs similarity index 73% rename from src/YamlMap/Serialization/ObjectFactory.cs rename to src/YamlMap/Serialization/ObjectBuilder.cs index 3c2d5dc..5d0ae86 100644 --- a/src/YamlMap/Serialization/ObjectFactory.cs +++ b/src/YamlMap/Serialization/ObjectBuilder.cs @@ -7,7 +7,7 @@ namespace YamlMap.Serialization /// /// Factory Class that generates instances of a type /// - public static class ObjectFactory + public static class ObjectBuilder { private static readonly Dictionary genericInterfaceImplementations = new Dictionary { @@ -25,24 +25,27 @@ public static class ObjectFactory { typeof(IDictionary), typeof(Dictionary) } }; + /// + /// Create a instance of the type + /// + /// + /// + /// + /// public static object CreateInstance(this Type type, IToken token) { if (type.IsArray) { - return Array.CreateInstance(type.GetElementType(), token.Count); + var arrayType = type.GetElementType(); + if(arrayType != null) + { + return ArrayInstanceFactory.Factory.CreateInstance(arrayType, token).Invoke(); + } } if (type.IsGenericTypeDefinition) { - var genericArgs = type.GetGenericArguments(); - var typeArgs = new Type[genericArgs.Length]; - for (var i = 0; i < genericArgs.Length; i++) - { - typeArgs[i] = typeof(object); - } - - var realizedType = type.MakeGenericType(typeArgs); - return realizedType.CreateInstance(token); + return GenericTypeInstanceFactory.Factory.CreateInstance(type, token).Invoke(); } if (type.IsInterface) @@ -70,7 +73,7 @@ public static object CreateInstance(this Type type, IToken token) try { - return Activator.CreateInstance(type); + return InstanceFactory.Factory.CreateInstance(type, token).Invoke(); } catch (Exception e) { diff --git a/src/YamlMap/Serialization/ObjectContract.cs b/src/YamlMap/Serialization/ObjectContract.cs new file mode 100644 index 0000000..37edf1a --- /dev/null +++ b/src/YamlMap/Serialization/ObjectContract.cs @@ -0,0 +1,26 @@ +using System; +using System.Reflection; + +namespace YamlMap.Serialization +{ + /// + /// Objectcontract for creating objects + /// + public class ObjectContract + { + /// + /// Gets the type that the object is of + /// + public Type Type { get; set; } + + /// + /// Gets the for creating the new object + /// + public ConstructorInfo Constructor { get; set; } + + /// + /// Gets a array of parameters used to create the object + /// + public object[] Parameters { get; set; } + } +} diff --git a/src/YamlMap/Serialization/TokenSerializer.cs b/src/YamlMap/Serialization/TokenSerializer.cs index 24ec1ed..0f62e3a 100644 --- a/src/YamlMap/Serialization/TokenSerializer.cs +++ b/src/YamlMap/Serialization/TokenSerializer.cs @@ -1,8 +1,6 @@ using System; using System.Collections; -using System.Linq; using System.Text; -using System.Xml.Schema; namespace YamlMap.Serialization { diff --git a/src/YamlMap/TokenExtensions.cs b/src/YamlMap/TokenExtensions.cs new file mode 100644 index 0000000..9402bd3 --- /dev/null +++ b/src/YamlMap/TokenExtensions.cs @@ -0,0 +1,32 @@ +using System; + +namespace YamlMap +{ + /// + /// Extensions for + /// + public static class TokenExtensions + { + /// + /// Gets all the childtokens from th + /// + /// + /// + public static IToken[] GetChildTokens(this IToken token) + { + if (token.Count == 0) + { + return Array.Empty(); + } + + var tokens = new IToken[token.Count]; + + for (var i = 0; i < token.Count; i++) + { + tokens[i] = token[i]; + } + + return tokens; + } + } +} diff --git a/src/YamlMap/YamlMap.csproj b/src/YamlMap/YamlMap.csproj index d64d500..3e81ab6 100644 --- a/src/YamlMap/YamlMap.csproj +++ b/src/YamlMap/YamlMap.csproj @@ -25,6 +25,7 @@ 1.0.0 1.0.0.0 1.0.0 + 9.0 diff --git a/src/YamlMap/YamlReader.cs b/src/YamlMap/YamlReader.cs index 5968cff..37d1ce5 100644 --- a/src/YamlMap/YamlReader.cs +++ b/src/YamlMap/YamlReader.cs @@ -56,12 +56,12 @@ public object Read(Type type, string yaml) /// public object Read(Type type, string[] lines) { - var deserializer = new TokenDeserializer(type, null); - var scanner = new Scanner(lines); var parser = new Parser(scanner); var tokens = parser.Parse(); + var deserializer = new TokenDeserializer(type, tokens); + for (var i = 0; i < tokens.Count; i++) { deserializer.Deserialize(tokens[i]);