From 3716f2ba02c5d1cd01ba962040de13005fb4eab4 Mon Sep 17 00:00:00 2001 From: fearppen Date: Mon, 25 Dec 2023 15:59:44 +0500 Subject: [PATCH 1/2] =?UTF-8?q?=D0=A0=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7=D0=BE?= =?UTF-8?q?=D0=B2=D0=B0=D0=BD=20=D0=BE=D1=81=D0=BD=D0=BE=D0=B2=D0=BD=D0=BE?= =?UTF-8?q?=D0=B9=20=D1=84=D1=83=D0=BD=D0=BA=D1=86=D0=B8=D0=BE=D0=BD=D0=B0?= =?UTF-8?q?=D0=BB,=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD?= =?UTF-8?q?=D0=B0=20=D0=B2=D0=BE=D0=B7=D0=BC=D0=BE=D0=B6=D0=BD=D0=BE=D1=81?= =?UTF-8?q?=D1=82=D1=8C=20=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D1=8B=20=D1=81=20?= =?UTF-8?q?=D0=BA=D0=BE=D0=BB=D0=BB=D0=B5=D0=BA=D1=86=D0=B8=D1=8F=D0=BC?= =?UTF-8?q?=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ObjectPrinting/IPrintingConfig.cs | 14 + ObjectPrinting/IPropertyPrintingConfig.cs | 9 + ObjectPrinting/ITypePrintingConfig.cs | 9 + ObjectPrinting/ObjectExtensions.cs | 9 + ObjectPrinting/ObjectPrinter.cs | 11 +- ObjectPrinting/ObjectPrinting.csproj | 9 +- ObjectPrinting/PrintingConfig.cs | 175 ++++++++++--- ObjectPrinting/PropertyPrintingConfig.cs | 28 ++ .../PropertyPrintingConfigExtensions.cs | 20 ++ ObjectPrinting/Solved/ObjectExtensions.cs | 10 - ObjectPrinting/Solved/ObjectPrinter.cs | 10 - ObjectPrinting/Solved/PrintingConfig.cs | 62 ----- .../Solved/PropertyPrintingConfig.cs | 32 --- .../PropertyPrintingConfigExtensions.cs | 18 -- .../Tests/ObjectPrinterAcceptanceTests.cs | 40 --- ObjectPrinting/Solved/Tests/Person.cs | 12 - .../Tests/ObjectPrinterAcceptanceTests.cs | 27 -- ObjectPrinting/Tests/Person.cs | 12 - ObjectPrinting/TypePrintingConfig.cs | 30 +++ ObjectPrintingTests/ObjectPrintingTests.cs | 244 ++++++++++++++++++ .../ObjectPrintingTests.csproj | 25 ++ ObjectPrintingTests/Person.cs | 9 + ObjectPrintingTests/PersonWithArray.cs | 6 + ObjectPrintingTests/PersonWithDictionary.cs | 6 + ObjectPrintingTests/PersonWithField.cs | 7 + ObjectPrintingTests/PersonWithList.cs | 6 + ObjectPrintingTests/PersonWithReference.cs | 8 + fluent-api.sln | 21 +- 28 files changed, 598 insertions(+), 271 deletions(-) create mode 100644 ObjectPrinting/IPrintingConfig.cs create mode 100644 ObjectPrinting/IPropertyPrintingConfig.cs create mode 100644 ObjectPrinting/ITypePrintingConfig.cs create mode 100644 ObjectPrinting/ObjectExtensions.cs create mode 100644 ObjectPrinting/PropertyPrintingConfig.cs create mode 100644 ObjectPrinting/PropertyPrintingConfigExtensions.cs delete mode 100644 ObjectPrinting/Solved/ObjectExtensions.cs delete mode 100644 ObjectPrinting/Solved/ObjectPrinter.cs delete mode 100644 ObjectPrinting/Solved/PrintingConfig.cs delete mode 100644 ObjectPrinting/Solved/PropertyPrintingConfig.cs delete mode 100644 ObjectPrinting/Solved/PropertyPrintingConfigExtensions.cs delete mode 100644 ObjectPrinting/Solved/Tests/ObjectPrinterAcceptanceTests.cs delete mode 100644 ObjectPrinting/Solved/Tests/Person.cs delete mode 100644 ObjectPrinting/Tests/ObjectPrinterAcceptanceTests.cs delete mode 100644 ObjectPrinting/Tests/Person.cs create mode 100644 ObjectPrinting/TypePrintingConfig.cs create mode 100644 ObjectPrintingTests/ObjectPrintingTests.cs create mode 100644 ObjectPrintingTests/ObjectPrintingTests.csproj create mode 100644 ObjectPrintingTests/Person.cs create mode 100644 ObjectPrintingTests/PersonWithArray.cs create mode 100644 ObjectPrintingTests/PersonWithDictionary.cs create mode 100644 ObjectPrintingTests/PersonWithField.cs create mode 100644 ObjectPrintingTests/PersonWithList.cs create mode 100644 ObjectPrintingTests/PersonWithReference.cs diff --git a/ObjectPrinting/IPrintingConfig.cs b/ObjectPrinting/IPrintingConfig.cs new file mode 100644 index 00000000..bb5ba420 --- /dev/null +++ b/ObjectPrinting/IPrintingConfig.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Reflection; + +namespace ObjectPrinting; + +public interface IPrintingConfig +{ + Dictionary> TypeSerializers { get; } + Dictionary> PropertySerializers { get; } + Dictionary Cultures { get; } + Dictionary PropertiesToTrim { get; } +} diff --git a/ObjectPrinting/IPropertyPrintingConfig.cs b/ObjectPrinting/IPropertyPrintingConfig.cs new file mode 100644 index 00000000..507abfad --- /dev/null +++ b/ObjectPrinting/IPropertyPrintingConfig.cs @@ -0,0 +1,9 @@ +using System.Reflection; + +namespace ObjectPrinting; + +public interface IPropertyPrintingConfig +{ + PrintingConfig ParentConfig { get; } + PropertyInfo Property { get; } +} \ No newline at end of file diff --git a/ObjectPrinting/ITypePrintingConfig.cs b/ObjectPrinting/ITypePrintingConfig.cs new file mode 100644 index 00000000..35ed693a --- /dev/null +++ b/ObjectPrinting/ITypePrintingConfig.cs @@ -0,0 +1,9 @@ +using System; +using System.Globalization; + +namespace ObjectPrinting; + +public interface ITypePrintingConfig +{ + PrintingConfig ParentConfig { get; } +} diff --git a/ObjectPrinting/ObjectExtensions.cs b/ObjectPrinting/ObjectExtensions.cs new file mode 100644 index 00000000..6879ab29 --- /dev/null +++ b/ObjectPrinting/ObjectExtensions.cs @@ -0,0 +1,9 @@ +namespace ObjectPrinting; + +public static class ObjectExtensions +{ + public static string PrintToString(this T obj) + { + return ObjectPrinter.For().PrintToString(obj); + } +} \ No newline at end of file diff --git a/ObjectPrinting/ObjectPrinter.cs b/ObjectPrinting/ObjectPrinter.cs index 3c7867c3..b2ce90a7 100644 --- a/ObjectPrinting/ObjectPrinter.cs +++ b/ObjectPrinting/ObjectPrinter.cs @@ -1,10 +1,9 @@ -namespace ObjectPrinting +namespace ObjectPrinting; + +public class ObjectPrinter { - public class ObjectPrinter + public static PrintingConfig For() { - public static PrintingConfig For() - { - return new PrintingConfig(); - } + return new PrintingConfig(); } } \ No newline at end of file diff --git a/ObjectPrinting/ObjectPrinting.csproj b/ObjectPrinting/ObjectPrinting.csproj index 1c5eaf1c..4892e6bb 100644 --- a/ObjectPrinting/ObjectPrinting.csproj +++ b/ObjectPrinting/ObjectPrinting.csproj @@ -1,14 +1,9 @@  - 8 - netcoreapp3.1 + 10 + net7.0 false - - - - - diff --git a/ObjectPrinting/PrintingConfig.cs b/ObjectPrinting/PrintingConfig.cs index a9e08211..8c4571cd 100644 --- a/ObjectPrinting/PrintingConfig.cs +++ b/ObjectPrinting/PrintingConfig.cs @@ -1,41 +1,158 @@ -using System; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Globalization; using System.Linq; +using System.Linq.Expressions; +using System.Reflection; using System.Text; -namespace ObjectPrinting +namespace ObjectPrinting; + +public class PrintingConfig : IPrintingConfig { - public class PrintingConfig + private readonly Dictionary cultures = new(); + private readonly Dictionary> typeSerializers = new(); + private readonly Dictionary> propertySerializers = new(); + private readonly Dictionary proprtiesToTrim = new(); + private readonly HashSet excludedProperties = new(); + private readonly HashSet excludedTypes = new(); + private readonly HashSet finalTypes = new() + { + typeof(int), + typeof(double), + typeof(float), + typeof(string), + typeof(DateTime), + typeof(TimeSpan) + }; + + Dictionary> IPrintingConfig.TypeSerializers => typeSerializers; + Dictionary IPrintingConfig.PropertiesToTrim => proprtiesToTrim; + Dictionary> IPrintingConfig.PropertySerializers => propertySerializers; + Dictionary IPrintingConfig.Cultures => cultures; + + public TypePrintingConfig For() + { + return new TypePrintingConfig(this); + } + + public PropertyPrintingConfig For(Expression> memberSelector) + { + return new PropertyPrintingConfig(this, GetPropertyInfo(memberSelector)); + } + + public PrintingConfig Excluding(Expression> memberSelector) + { + var property = GetPropertyInfo(memberSelector); + excludedProperties.Add(property); + return this; + } + + public PrintingConfig Excluding() + { + excludedTypes.Add(typeof(TPropType)); + return this; + } + + private PropertyInfo GetPropertyInfo(Expression> expression) { - public string PrintToString(TOwner obj) + if (expression.Body is MemberExpression member) { - return PrintToString(obj, 0); + return (PropertyInfo)member.Member; } + throw new ArgumentException("please, choose property"); + } + + public string PrintToString(TOwner obj) + { + return PrintToString(obj, 0, new HashSet()); + } + + private string PrintToString(object obj, int nestingLevel, HashSet printed) + { + if (obj == null) + return "null" + Environment.NewLine; + var type = obj.GetType(); - private string PrintToString(object obj, int nestingLevel) + if (finalTypes.Contains(type)) + return obj + Environment.NewLine; + + if (printed.Contains(obj)) + return "this " + type.Name + Environment.NewLine; + printed.Add(obj); + + if (obj is IEnumerable collection) + return PrintCollection(collection, nestingLevel, printed); + if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Dictionary<,>)) + return PrintDictionary(obj, nestingLevel, printed); + var sb = new StringBuilder(); + sb.AppendLine(type.Name); + sb = PrintNestingElements(sb, obj, nestingLevel, printed); + return sb.ToString(); + } + + private string PrintCollection(IEnumerable collection, int nestingLevel, HashSet printed) + { + var sb = new StringBuilder(); + var identation = new string('\t', nestingLevel + 1); + if (!collection.GetEnumerator().MoveNext()) + return ("Empty" + Environment.NewLine); + foreach (var item in collection) { - //TODO apply configurations - if (obj == null) - return "null" + Environment.NewLine; - - var finalTypes = new[] - { - typeof(int), typeof(double), typeof(float), typeof(string), - typeof(DateTime), typeof(TimeSpan) - }; - if (finalTypes.Contains(obj.GetType())) - return obj + Environment.NewLine; - - var identation = new string('\t', nestingLevel + 1); - var sb = new StringBuilder(); - var type = obj.GetType(); - sb.AppendLine(type.Name); - foreach (var propertyInfo in type.GetProperties()) - { - sb.Append(identation + propertyInfo.Name + " = " + - PrintToString(propertyInfo.GetValue(obj), - nestingLevel + 1)); - } - return sb.ToString(); + sb.Append(identation + PrintToString(item, nestingLevel + 1, printed)); } + return sb.ToString(); + } + + private string PrintDictionary(object obj, int nestingLevel, HashSet printed) + { + var dict = (IDictionary)obj; + if (!dict.GetEnumerator().MoveNext()) + return ("Empty" + Environment.NewLine); + var sb = new StringBuilder(); + var identation = new string('\t', nestingLevel + 1); + foreach (var pair in dict) + { + var key = ((DictionaryEntry)pair).Key; + var value = ((DictionaryEntry)pair).Value; + sb.Append(identation + PrintToString(key, nestingLevel, printed).Trim() + + " : " + + PrintToString(value, nestingLevel, printed).Trim() + + Environment.NewLine); + } + return sb.ToString(); + } + + private StringBuilder PrintNestingElements(StringBuilder sb, object obj, int nestingLevel, HashSet printed) + { + var type = obj.GetType(); + var identation = new string('\t', nestingLevel + 1); + foreach (var property in type.GetProperties()) + { + if (!excludedTypes.Contains(property.PropertyType) && !excludedProperties.Contains(property)) + sb.Append(identation + property.Name + + " = " + + PrintProperty(property, property.GetValue(obj), nestingLevel + 1, printed)); + } + return sb; + } + + private string PrintProperty(PropertyInfo property, object obj, int nestingLevel, HashSet printed) + { + string result = null; + if (cultures.TryGetValue(property.PropertyType, out var culture)) + result = string.Format(culture, "{0}", obj); + if (typeSerializers.TryGetValue(property.PropertyType, out var typeSerialize)) + result = typeSerialize.Invoke(obj); + if (propertySerializers.TryGetValue(property, out var propertySerialize)) + result = propertySerialize.Invoke(obj); + if (proprtiesToTrim.TryGetValue(property, out var trim)) + { + result ??= obj as string; + result = result[..Math.Min(result.Length, trim)]; + } + + return result is null ? PrintToString(obj, nestingLevel, printed) : result + Environment.NewLine; } } \ No newline at end of file diff --git a/ObjectPrinting/PropertyPrintingConfig.cs b/ObjectPrinting/PropertyPrintingConfig.cs new file mode 100644 index 00000000..8c97f8b9 --- /dev/null +++ b/ObjectPrinting/PropertyPrintingConfig.cs @@ -0,0 +1,28 @@ +using System; +using System.Reflection; + +namespace ObjectPrinting; + +public class PropertyPrintingConfig : IPropertyPrintingConfig +{ + private readonly PrintingConfig printingConfig; + private readonly PropertyInfo propertyInfo; + + public PropertyPrintingConfig(PrintingConfig printingConfig, PropertyInfo property) + { + this.printingConfig = printingConfig; + propertyInfo = property; + } + + public PrintingConfig Using(Func print) + { + var config = (IPrintingConfig)printingConfig; + config.PropertySerializers[propertyInfo] = p => print((TPropType)p); + + return printingConfig; + } + + PrintingConfig IPropertyPrintingConfig.ParentConfig => printingConfig; + + PropertyInfo IPropertyPrintingConfig.Property => propertyInfo; +} \ No newline at end of file diff --git a/ObjectPrinting/PropertyPrintingConfigExtensions.cs b/ObjectPrinting/PropertyPrintingConfigExtensions.cs new file mode 100644 index 00000000..8a0b181d --- /dev/null +++ b/ObjectPrinting/PropertyPrintingConfigExtensions.cs @@ -0,0 +1,20 @@ +using System; + +namespace ObjectPrinting; + +public static class PropertyPrintingConfigExtensions +{ + public static string PrintToString(this T obj, Func, PrintingConfig> config) + { + return config(ObjectPrinter.For()).PrintToString(obj); + } + + public static PrintingConfig TrimmedToLength(this PropertyPrintingConfig propConfig, int maxLen) + { + var propertyConfig = (IPropertyPrintingConfig)propConfig; + var printingConfig = (IPrintingConfig)propertyConfig.ParentConfig; + printingConfig.PropertiesToTrim[propertyConfig.Property] = maxLen; + return propertyConfig.ParentConfig; + } + +} \ No newline at end of file diff --git a/ObjectPrinting/Solved/ObjectExtensions.cs b/ObjectPrinting/Solved/ObjectExtensions.cs deleted file mode 100644 index b0c94553..00000000 --- a/ObjectPrinting/Solved/ObjectExtensions.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace ObjectPrinting.Solved -{ - public static class ObjectExtensions - { - public static string PrintToString(this T obj) - { - return ObjectPrinter.For().PrintToString(obj); - } - } -} \ No newline at end of file diff --git a/ObjectPrinting/Solved/ObjectPrinter.cs b/ObjectPrinting/Solved/ObjectPrinter.cs deleted file mode 100644 index 540ee769..00000000 --- a/ObjectPrinting/Solved/ObjectPrinter.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace ObjectPrinting.Solved -{ - public class ObjectPrinter - { - public static PrintingConfig For() - { - return new PrintingConfig(); - } - } -} \ No newline at end of file diff --git a/ObjectPrinting/Solved/PrintingConfig.cs b/ObjectPrinting/Solved/PrintingConfig.cs deleted file mode 100644 index 0ec5aeb2..00000000 --- a/ObjectPrinting/Solved/PrintingConfig.cs +++ /dev/null @@ -1,62 +0,0 @@ -using System; -using System.Linq; -using System.Linq.Expressions; -using System.Text; - -namespace ObjectPrinting.Solved -{ - public class PrintingConfig - { - public PropertyPrintingConfig Printing() - { - return new PropertyPrintingConfig(this); - } - - public PropertyPrintingConfig Printing(Expression> memberSelector) - { - return new PropertyPrintingConfig(this); - } - - public PrintingConfig Excluding(Expression> memberSelector) - { - return this; - } - - internal PrintingConfig Excluding() - { - return this; - } - - public string PrintToString(TOwner obj) - { - return PrintToString(obj, 0); - } - - private string PrintToString(object obj, int nestingLevel) - { - //TODO apply configurations - if (obj == null) - return "null" + Environment.NewLine; - - var finalTypes = new[] - { - typeof(int), typeof(double), typeof(float), typeof(string), - typeof(DateTime), typeof(TimeSpan) - }; - if (finalTypes.Contains(obj.GetType())) - return obj + Environment.NewLine; - - var identation = new string('\t', nestingLevel + 1); - var sb = new StringBuilder(); - var type = obj.GetType(); - sb.AppendLine(type.Name); - foreach (var propertyInfo in type.GetProperties()) - { - sb.Append(identation + propertyInfo.Name + " = " + - PrintToString(propertyInfo.GetValue(obj), - nestingLevel + 1)); - } - return sb.ToString(); - } - } -} \ No newline at end of file diff --git a/ObjectPrinting/Solved/PropertyPrintingConfig.cs b/ObjectPrinting/Solved/PropertyPrintingConfig.cs deleted file mode 100644 index a509697d..00000000 --- a/ObjectPrinting/Solved/PropertyPrintingConfig.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System; -using System.Globalization; - -namespace ObjectPrinting.Solved -{ - public class PropertyPrintingConfig : IPropertyPrintingConfig - { - private readonly PrintingConfig printingConfig; - - public PropertyPrintingConfig(PrintingConfig printingConfig) - { - this.printingConfig = printingConfig; - } - - public PrintingConfig Using(Func print) - { - return printingConfig; - } - - public PrintingConfig Using(CultureInfo culture) - { - return printingConfig; - } - - PrintingConfig IPropertyPrintingConfig.ParentConfig => printingConfig; - } - - public interface IPropertyPrintingConfig - { - PrintingConfig ParentConfig { get; } - } -} \ No newline at end of file diff --git a/ObjectPrinting/Solved/PropertyPrintingConfigExtensions.cs b/ObjectPrinting/Solved/PropertyPrintingConfigExtensions.cs deleted file mode 100644 index dd392239..00000000 --- a/ObjectPrinting/Solved/PropertyPrintingConfigExtensions.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System; - -namespace ObjectPrinting.Solved -{ - public static class PropertyPrintingConfigExtensions - { - public static string PrintToString(this T obj, Func, PrintingConfig> config) - { - return config(ObjectPrinter.For()).PrintToString(obj); - } - - public static PrintingConfig TrimmedToLength(this PropertyPrintingConfig propConfig, int maxLen) - { - return ((IPropertyPrintingConfig)propConfig).ParentConfig; - } - - } -} \ No newline at end of file diff --git a/ObjectPrinting/Solved/Tests/ObjectPrinterAcceptanceTests.cs b/ObjectPrinting/Solved/Tests/ObjectPrinterAcceptanceTests.cs deleted file mode 100644 index ac52d5ee..00000000 --- a/ObjectPrinting/Solved/Tests/ObjectPrinterAcceptanceTests.cs +++ /dev/null @@ -1,40 +0,0 @@ -using System; -using System.Globalization; -using NUnit.Framework; - -namespace ObjectPrinting.Solved.Tests -{ - [TestFixture] - public class ObjectPrinterAcceptanceTests - { - [Test] - public void Demo() - { - var person = new Person { Name = "Alex", Age = 19 }; - - var printer = ObjectPrinter.For() - //1. Исключить из сериализации свойства определенного типа - .Excluding() - //2. Указать альтернативный способ сериализации для определенного типа - .Printing().Using(i => i.ToString("X")) - //3. Для числовых типов указать культуру - .Printing().Using(CultureInfo.InvariantCulture) - //4. Настроить сериализацию конкретного свойства - //5. Настроить обрезание строковых свойств (метод должен быть виден только для строковых свойств) - .Printing(p => p.Name).TrimmedToLength(10) - //6. Исключить из сериализации конкретного свойства - .Excluding(p => p.Age); - - string s1 = printer.PrintToString(person); - - //7. Синтаксический сахар в виде метода расширения, сериализующего по-умолчанию - string s2 = person.PrintToString(); - - //8. ...с конфигурированием - string s3 = person.PrintToString(s => s.Excluding(p => p.Age)); - Console.WriteLine(s1); - Console.WriteLine(s2); - Console.WriteLine(s3); - } - } -} \ No newline at end of file diff --git a/ObjectPrinting/Solved/Tests/Person.cs b/ObjectPrinting/Solved/Tests/Person.cs deleted file mode 100644 index 858ebbf8..00000000 --- a/ObjectPrinting/Solved/Tests/Person.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; - -namespace ObjectPrinting.Solved.Tests -{ - public class Person - { - public Guid Id { get; set; } - public string Name { get; set; } - public double Height { get; set; } - public int Age { get; set; } - } -} \ No newline at end of file diff --git a/ObjectPrinting/Tests/ObjectPrinterAcceptanceTests.cs b/ObjectPrinting/Tests/ObjectPrinterAcceptanceTests.cs deleted file mode 100644 index 4c8b2445..00000000 --- a/ObjectPrinting/Tests/ObjectPrinterAcceptanceTests.cs +++ /dev/null @@ -1,27 +0,0 @@ -using NUnit.Framework; - -namespace ObjectPrinting.Tests -{ - [TestFixture] - public class ObjectPrinterAcceptanceTests - { - [Test] - public void Demo() - { - var person = new Person { Name = "Alex", Age = 19 }; - - var printer = ObjectPrinter.For(); - //1. Исключить из сериализации свойства определенного типа - //2. Указать альтернативный способ сериализации для определенного типа - //3. Для числовых типов указать культуру - //4. Настроить сериализацию конкретного свойства - //5. Настроить обрезание строковых свойств (метод должен быть виден только для строковых свойств) - //6. Исключить из сериализации конкретного свойства - - string s1 = printer.PrintToString(person); - - //7. Синтаксический сахар в виде метода расширения, сериализующего по-умолчанию - //8. ...с конфигурированием - } - } -} \ No newline at end of file diff --git a/ObjectPrinting/Tests/Person.cs b/ObjectPrinting/Tests/Person.cs deleted file mode 100644 index f9555955..00000000 --- a/ObjectPrinting/Tests/Person.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; - -namespace ObjectPrinting.Tests -{ - public class Person - { - public Guid Id { get; set; } - public string Name { get; set; } - public double Height { get; set; } - public int Age { get; set; } - } -} \ No newline at end of file diff --git a/ObjectPrinting/TypePrintingConfig.cs b/ObjectPrinting/TypePrintingConfig.cs new file mode 100644 index 00000000..b4436878 --- /dev/null +++ b/ObjectPrinting/TypePrintingConfig.cs @@ -0,0 +1,30 @@ +using System; +using System.Globalization; + +namespace ObjectPrinting; + +public class TypePrintingConfig : ITypePrintingConfig +{ + private readonly PrintingConfig printingConfig; + + public TypePrintingConfig(PrintingConfig printingConfig) + { + this.printingConfig = printingConfig; + } + + PrintingConfig ITypePrintingConfig.ParentConfig => printingConfig; + + public PrintingConfig Using(Func print) + { + var config = (IPrintingConfig)printingConfig; + config.TypeSerializers[typeof(TType)] = t => print((TType)t); + return printingConfig; + } + + public PrintingConfig Using(CultureInfo culture) + { + var config = (IPrintingConfig)printingConfig; + config.Cultures[typeof(TType)] = culture; + return printingConfig; + } +} diff --git a/ObjectPrintingTests/ObjectPrintingTests.cs b/ObjectPrintingTests/ObjectPrintingTests.cs new file mode 100644 index 00000000..e3968610 --- /dev/null +++ b/ObjectPrintingTests/ObjectPrintingTests.cs @@ -0,0 +1,244 @@ +using FluentAssertions; +using NUnit.Framework; +using ObjectPrinting; +using System.Globalization; + +namespace ObjectPrintingTests; + +public class ObjectPrintingTests +{ + private readonly Person person = new() { Age = 20, Height = 178.5, Name = "Test" }; + + [Test] + public void PrintToString_SimplePersonClass_ReturnsStringWithAllPorperties() + { + var result = ObjectPrinter.For().PrintToString(person); + var expected = "Person\r\n\tId = Guid\r\n\tName = Test\r\n\tHeight = 178,5\r\n\tAge = 20\r\n"; + result.Should().BeEquivalentTo(expected); + } + + [Test] + public void PrintToString_WithExcludeType_ReturnsCorrectString() + { + var result = ObjectPrinter + .For() + .Excluding() + .PrintToString(person); + var expected = "Person\r\n\tName = Test\r\n\tHeight = 178,5\r\n\tAge = 20\r\n"; + result.Should().BeEquivalentTo(expected); + } + + [Test] + public void PrintToString_WithExcludeProperty_ReturnsCorrectString() + { + var result = ObjectPrinter + .For() + .Excluding(p => p.Id) + .PrintToString(person); + var expected = "Person\r\n\tName = Test\r\n\tHeight = 178,5\r\n\tAge = 20\r\n"; + result.Should().BeEquivalentTo(expected); + } + + [Test] + public void PrintToString_WithCustomSerializeType_ReturnsCorrectString() + { + var result = ObjectPrinter + .For() + .For() + .Using(i => "x") + .PrintToString(person); + var expected = "Person\r\n\tId = Guid\r\n\tName = Test\r\n\tHeight = 178,5\r\n\tAge = x\r\n"; + result.Should().BeEquivalentTo(expected); + } + + [Test] + public void PrintToString_WithCustomSerializeProperty_ReturnsCorrectString() + { + var result = ObjectPrinter + .For() + .For(p => p.Id) + .Using(id => "x") + .PrintToString(person); + var expected = "Person\r\n\tId = x\r\n\tName = Test\r\n\tHeight = 178,5\r\n\tAge = 20\r\n"; + result.Should().BeEquivalentTo(expected); + } + + [Test] + public void PrintToString_WithCulture_ReturnsCorrectString() + { + var result = ObjectPrinter + .For() + .For() + .Using(new CultureInfo("en-US")) + .PrintToString(person); + var expected = "Person\r\n\tId = Guid\r\n\tName = Test\r\n\tHeight = 178.5\r\n\tAge = 20\r\n"; + result.Should().BeEquivalentTo(expected); + } + + [Test] + public void PrintToString_WithTrimmedString_ReturnsCorrectString() + { + var result = ObjectPrinter + .For() + .For(p => p.Name) + .TrimmedToLength(2) + .PrintToString(person); + var expected = "Person\r\n\tId = Guid\r\n\tName = Te\r\n\tHeight = 178,5\r\n\tAge = 20\r\n"; + result.Should().BeEquivalentTo(expected); + } + + [Test] + public void PrintToString_WithList_ReturnsCorrectString() + { + var person = new PersonWithList() { FriendNames = new List { "1", "2", "3", "4" } }; + var result = ObjectPrinter + .For() + .PrintToString(person); + var expected = "PersonWithList\r\n\tFriendNames = \t\t1\r\n\t\t2\r\n\t\t3\r\n\t\t4\r\n"; + result.Should().BeEquivalentTo(expected); + } + + [Test] + public void PrintToString_PersonWithArray_ReturnsCorrectString() + { + var person = new PersonWithArray() { FriendNames = new string[] { "name1", "name2", "name3" } }; + var result = ObjectPrinter + .For() + .PrintToString(person); + var expected = "PersonWithArray\r\n\tFriendNames = \t\tname1\r\n\t\tname2\r\n\t\tname3\r\n"; + result.Should().BeEquivalentTo(expected); + } + + [Test] + public void PrintToString_PersonWithDictionary_ReturnsCorrectString() + { + var person = new PersonWithDictionary() { Friends = new Dictionary + { + { 1, "name1" }, { 2, "name2" }, { 3, "name3" } + }}; + var result = ObjectPrinter + .For() + .PrintToString(person); + var expected = "PersonWithDictionary\r\n\tFriends = \t\t1 : name1\r\n\t\t2 : name2\r\n\t\t3 : name3\r\n"; + result.Should().BeEquivalentTo(expected); + } + + [Test] + public void PrintToString_CollectionEmpty_ReturnsCorrectString() + { + var person = new PersonWithArray() { FriendNames = Array.Empty() }; + var result = ObjectPrinter + .For() + .PrintToString(person); + var expected = "PersonWithArray\r\n\tFriendNames = Empty\r\n"; + result.Should().BeEquivalentTo(expected); + } + + [Test] + public void PrintToString_WithCyclicReference_ReturnsCorrectString() + { + var person = new PersonWithReference { Id = 0, Name = "Anton"}; + person.Friend = person; + var result = ObjectPrinter + .For() + .PrintToString(person); + var expected = "PersonWithReference\r\n\tId = 0\r\n\tName = Anton\r\n\tFriend = this PersonWithReference\r\n"; + result.Should().BeEquivalentTo(expected); + } + + [Test] + public void PrintToString_PersonWithReference_ReturnsCorrectString() + { + var person = new PersonWithReference { Id = 0, Name = "Anton" }; + person.Friend = new PersonWithReference { Friend = null, Id = 0, Name = "Andrey"}; + var result = ObjectPrinter + .For() + .PrintToString(person); + var expected = $"PersonWithReference\r\n\tId = 0\r\n\t" + + $"Name = Anton\r\n\t" + + $"Friend = PersonWithReference\r\n\t\t" + + $"Id = 0\r\n\t\t" + + $"Name = Andrey\r\n\t\tFriend = null\r\n"; + result.Should().BeEquivalentTo(expected); + } + + [Test] + public void PrintToString_PropertyTrimTwice_ReturnsCorrectString() + { + var person = new Person { Age = 10, Name = "Anton" }; + var result = ObjectPrinter + .For() + .For(p => p.Name) + .TrimmedToLength(1) + .For(p => p.Name) + .TrimmedToLength(2) + .PrintToString(person); + var expected = "Person\r\n\tId = Guid\r\n\tName = An\r\n\tHeight = 0\r\n\tAge = 10\r\n"; + result.Should().BeEquivalentTo(expected); + } + + [Test] + public void PrintToString_TwoTypesSerializingProperty_ReturnsCorrectStringWithLastSerializing() + { + var person = new Person { Age = 10, Name = "Anton" }; + var result = ObjectPrinter + .For() + .For(p => p.Age) + .Using(a => "x") + .For(p => p.Age) + .Using(a => "y") + .PrintToString(person); + var expected = "Person\r\n\tId = Guid\r\n\tName = Anton\r\n\tHeight = 0\r\n\tAge = y\r\n"; + result.Should().BeEquivalentTo(expected); + } + + [Test] + public void PrintToString_TwoTypesSerializingType_ReturnsCorrectStringWithLastSerializing() + { + var person = new Person { Age = 10, Name = "Anton" }; + var result = ObjectPrinter + .For() + .For() + .Using(i => "x") + .For() + .Using(i => "y") + .PrintToString(person); + var expected = "Person\r\n\tId = Guid\r\n\tName = Anton\r\n\tHeight = 0\r\n\tAge = y\r\n"; + result.Should().BeEquivalentTo(expected); + } + + [Test] + public void PrintToString_PropertyExcludeTwice_ReturnsCorrectString() + { + var person = new Person { Age = 10, Name = "Anton" }; + var result = ObjectPrinter + .For() + .Excluding(p => p.Age) + .PrintToString(person); + var expected = "Person\r\n\tId = Guid\r\n\tName = Anton\r\n\tHeight = 0\r\n"; + result.Should().BeEquivalentTo(expected); + } + + [Test] + public void PrintToString_TypeExcludeTwice_ReturnsCorrectString() + { + var person = new Person { Age = 10, Name = "Anton" }; + var result = ObjectPrinter + .For() + .Excluding() + .PrintToString(person); + var expected = "Person\r\n\tId = Guid\r\n\tName = Anton\r\n\tHeight = 0\r\n"; + result.Should().BeEquivalentTo(expected); + } + + [Test] + public void PrintToString_WithField_ReturnsCorrectString() + { + var person = new PersonWithField { Age = 10, Name = "Anton" }; + var result = ObjectPrinter + .For() + .PrintToString(person); + var expected = "Person\r\n\tId = Guid\r\n\tName = Anton\r\n\tHeight = 0\r\n"; + result.Should().BeEquivalentTo(expected); + } +} \ No newline at end of file diff --git a/ObjectPrintingTests/ObjectPrintingTests.csproj b/ObjectPrintingTests/ObjectPrintingTests.csproj new file mode 100644 index 00000000..3173ff7b --- /dev/null +++ b/ObjectPrintingTests/ObjectPrintingTests.csproj @@ -0,0 +1,25 @@ + + + + net7.0 + enable + enable + + false + true + + + + + + + + + + + + + + + + diff --git a/ObjectPrintingTests/Person.cs b/ObjectPrintingTests/Person.cs new file mode 100644 index 00000000..40145aa9 --- /dev/null +++ b/ObjectPrintingTests/Person.cs @@ -0,0 +1,9 @@ +namespace ObjectPrintingTests; + +public class Person +{ + public Guid Id { get; set; } + public string Name { get; set; } + public double Height { get; set; } + public int Age { get; set; } +} diff --git a/ObjectPrintingTests/PersonWithArray.cs b/ObjectPrintingTests/PersonWithArray.cs new file mode 100644 index 00000000..43c05369 --- /dev/null +++ b/ObjectPrintingTests/PersonWithArray.cs @@ -0,0 +1,6 @@ +namespace ObjectPrintingTests; + +public class PersonWithArray +{ + public string[] FriendNames { get; set; } +} diff --git a/ObjectPrintingTests/PersonWithDictionary.cs b/ObjectPrintingTests/PersonWithDictionary.cs new file mode 100644 index 00000000..e146b070 --- /dev/null +++ b/ObjectPrintingTests/PersonWithDictionary.cs @@ -0,0 +1,6 @@ +namespace ObjectPrintingTests; + +public class PersonWithDictionary +{ + public Dictionary Friends { get; set; } +} diff --git a/ObjectPrintingTests/PersonWithField.cs b/ObjectPrintingTests/PersonWithField.cs new file mode 100644 index 00000000..6ec6a70e --- /dev/null +++ b/ObjectPrintingTests/PersonWithField.cs @@ -0,0 +1,7 @@ +namespace ObjectPrintingTests; + +public class PersonWithField +{ + public string Name; + public int Age; +} diff --git a/ObjectPrintingTests/PersonWithList.cs b/ObjectPrintingTests/PersonWithList.cs new file mode 100644 index 00000000..13ac4c06 --- /dev/null +++ b/ObjectPrintingTests/PersonWithList.cs @@ -0,0 +1,6 @@ +namespace ObjectPrintingTests; + +public class PersonWithList +{ + public List FriendNames { get; set; } +} diff --git a/ObjectPrintingTests/PersonWithReference.cs b/ObjectPrintingTests/PersonWithReference.cs new file mode 100644 index 00000000..5fb73043 --- /dev/null +++ b/ObjectPrintingTests/PersonWithReference.cs @@ -0,0 +1,8 @@ +namespace ObjectPrintingTests; + +public class PersonWithReference +{ + public int Id { get; set; } + public string Name { get; set; } + public PersonWithReference Friend { get; set; } +} diff --git a/fluent-api.sln b/fluent-api.sln index 69c8db9e..3f005275 100644 --- a/fluent-api.sln +++ b/fluent-api.sln @@ -1,17 +1,19 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.25123.0 +# Visual Studio Version 17 +VisualStudioVersion = 17.7.34024.191 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ObjectPrinting", "ObjectPrinting\ObjectPrinting.csproj", "{07B8C9B7-8289-46CB-9875-048A57758EEE}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ObjectPrinting", "ObjectPrinting\ObjectPrinting.csproj", "{07B8C9B7-8289-46CB-9875-048A57758EEE}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Samples", "Samples", "{6D308E4A-CEC7-4536-9B87-81CD337A87AD}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FluentMapping", "Samples\FluentMapper\FluentMapping.csproj", "{FEEA5AFE-459A-4D13-81D0-252E1A2E6F4E}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FluentMapping", "Samples\FluentMapper\FluentMapping.csproj", "{FEEA5AFE-459A-4D13-81D0-252E1A2E6F4E}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FluentMapping.Tests", "Samples\FluentMapper.Tests\FluentMapping.Tests.csproj", "{8A7BB3EA-3E6A-4D04-A801-D5CD1620DA0D}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FluentMapping.Tests", "Samples\FluentMapper.Tests\FluentMapping.Tests.csproj", "{8A7BB3EA-3E6A-4D04-A801-D5CD1620DA0D}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Spectacle", "Samples\Spectacle\Spectacle.csproj", "{EFA9335C-411B-4597-B0B6-5438D1AE04C3}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Spectacle", "Samples\Spectacle\Spectacle.csproj", "{EFA9335C-411B-4597-B0B6-5438D1AE04C3}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ObjectPrintingTests", "ObjectPrintingTests\ObjectPrintingTests.csproj", "{BDBCE37D-8EBB-422D-8783-0E63D1AFDE73}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -35,6 +37,10 @@ Global {EFA9335C-411B-4597-B0B6-5438D1AE04C3}.Debug|Any CPU.Build.0 = Debug|Any CPU {EFA9335C-411B-4597-B0B6-5438D1AE04C3}.Release|Any CPU.ActiveCfg = Release|Any CPU {EFA9335C-411B-4597-B0B6-5438D1AE04C3}.Release|Any CPU.Build.0 = Release|Any CPU + {BDBCE37D-8EBB-422D-8783-0E63D1AFDE73}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BDBCE37D-8EBB-422D-8783-0E63D1AFDE73}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BDBCE37D-8EBB-422D-8783-0E63D1AFDE73}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BDBCE37D-8EBB-422D-8783-0E63D1AFDE73}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -44,4 +50,7 @@ Global {8A7BB3EA-3E6A-4D04-A801-D5CD1620DA0D} = {6D308E4A-CEC7-4536-9B87-81CD337A87AD} {EFA9335C-411B-4597-B0B6-5438D1AE04C3} = {6D308E4A-CEC7-4536-9B87-81CD337A87AD} EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {8C4DC7B4-9312-42AA-BBE3-CF528DE13D07} + EndGlobalSection EndGlobal From db1d40a5c71f7393fde916d03618c228188da0ec Mon Sep 17 00:00:00 2001 From: fearppen Date: Mon, 25 Dec 2023 16:35:24 +0500 Subject: [PATCH 2/2] =?UTF-8?q?=D0=9D=D0=B5=D0=B1=D0=BE=D0=BB=D1=8C=D1=88?= =?UTF-8?q?=D0=BE=D0=B9=20=D1=80=D0=B5=D1=84=D0=B0=D0=BA=D1=82=D0=BE=D1=80?= =?UTF-8?q?=D0=B8=D0=BD=D0=B3=20=D0=BA=D0=BE=D0=B4=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ObjectPrinting/ITypePrintingConfig.cs | 5 +---- ObjectPrinting/PrintingConfig.cs | 1 - ObjectPrintingTests/ObjectPrintingTests.cs | 11 ----------- 3 files changed, 1 insertion(+), 16 deletions(-) diff --git a/ObjectPrinting/ITypePrintingConfig.cs b/ObjectPrinting/ITypePrintingConfig.cs index 35ed693a..b5992249 100644 --- a/ObjectPrinting/ITypePrintingConfig.cs +++ b/ObjectPrinting/ITypePrintingConfig.cs @@ -1,7 +1,4 @@ -using System; -using System.Globalization; - -namespace ObjectPrinting; +namespace ObjectPrinting; public interface ITypePrintingConfig { diff --git a/ObjectPrinting/PrintingConfig.cs b/ObjectPrinting/PrintingConfig.cs index 8c4571cd..5a0a615e 100644 --- a/ObjectPrinting/PrintingConfig.cs +++ b/ObjectPrinting/PrintingConfig.cs @@ -2,7 +2,6 @@ using System.Collections; using System.Collections.Generic; using System.Globalization; -using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Text; diff --git a/ObjectPrintingTests/ObjectPrintingTests.cs b/ObjectPrintingTests/ObjectPrintingTests.cs index e3968610..c990796f 100644 --- a/ObjectPrintingTests/ObjectPrintingTests.cs +++ b/ObjectPrintingTests/ObjectPrintingTests.cs @@ -230,15 +230,4 @@ public void PrintToString_TypeExcludeTwice_ReturnsCorrectString() var expected = "Person\r\n\tId = Guid\r\n\tName = Anton\r\n\tHeight = 0\r\n"; result.Should().BeEquivalentTo(expected); } - - [Test] - public void PrintToString_WithField_ReturnsCorrectString() - { - var person = new PersonWithField { Age = 10, Name = "Anton" }; - var result = ObjectPrinter - .For() - .PrintToString(person); - var expected = "Person\r\n\tId = Guid\r\n\tName = Anton\r\n\tHeight = 0\r\n"; - result.Should().BeEquivalentTo(expected); - } } \ No newline at end of file