diff --git a/.gitignore b/.gitignore index a1f46668..ca8ba029 100644 --- a/.gitignore +++ b/.gitignore @@ -236,3 +236,5 @@ _Pvt_Extensions .fake/ .idea/ + +ObjectPrinting/Tests/Snapshots/*.received.txt \ No newline at end of file diff --git a/ObjectPrinting/Interfaces/IPrintingConfig.cs b/ObjectPrinting/Interfaces/IPrintingConfig.cs new file mode 100644 index 00000000..6076527a --- /dev/null +++ b/ObjectPrinting/Interfaces/IPrintingConfig.cs @@ -0,0 +1,8 @@ +using System; + +namespace ObjectPrinting.Interfaces; + +public interface IPrintingConfig +{ + public PrintingConfig Using(Func print); +} \ No newline at end of file diff --git a/ObjectPrinting/MemberInfoExtensions.cs b/ObjectPrinting/MemberInfoExtensions.cs new file mode 100644 index 00000000..a8977835 --- /dev/null +++ b/ObjectPrinting/MemberInfoExtensions.cs @@ -0,0 +1,27 @@ +using System; +using System.Reflection; + +namespace ObjectPrinting; + +internal static class MemberInfoExtensions +{ + public static object? GetValue(this MemberInfo memberInfo, object? obj) + { + return memberInfo.MemberType switch + { + MemberTypes.Field => ((FieldInfo)memberInfo).GetValue(obj), + MemberTypes.Property => ((PropertyInfo)memberInfo).GetValue(obj), + _ => throw new ArgumentException($"Member type {memberInfo.MemberType} is not supported.") + }; + } + + public static Type GetMemberType(this MemberInfo memberInfo) + { + return memberInfo.MemberType switch + { + MemberTypes.Field => ((FieldInfo)memberInfo).FieldType, + MemberTypes.Property => ((PropertyInfo)memberInfo).PropertyType, + _ => throw new ArgumentException($"Member type {memberInfo.MemberType} is not supported.") + }; + } +} \ No newline at end of file diff --git a/ObjectPrinting/MemberPrintingConfig.cs b/ObjectPrinting/MemberPrintingConfig.cs new file mode 100644 index 00000000..c0337028 --- /dev/null +++ b/ObjectPrinting/MemberPrintingConfig.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using ObjectPrinting.Interfaces; + +namespace ObjectPrinting; + +public class MemberPrintingConfig : IPrintingConfig +{ + private readonly PrintingConfig parent; + private readonly Dictionary> customSerializers; + private readonly MemberInfo memberInfo; + + public MemberPrintingConfig(PrintingConfig parent, + Dictionary> customSerializers, + MemberInfo memberInfo) + { + this.parent = parent; + this.customSerializers = customSerializers; + this.memberInfo = memberInfo; + } + + public PrintingConfig Using(Func print) + { + customSerializers[memberInfo] = obj => print((TPropType)obj); + return parent; + } +} \ No newline at end of file diff --git a/ObjectPrinting/ObjectExtensions.cs b/ObjectPrinting/ObjectExtensions.cs new file mode 100644 index 00000000..f2ef5db7 --- /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/ObjectPrinting.csproj b/ObjectPrinting/ObjectPrinting.csproj index c5db392f..20476c40 100644 --- a/ObjectPrinting/ObjectPrinting.csproj +++ b/ObjectPrinting/ObjectPrinting.csproj @@ -8,5 +8,6 @@ + diff --git a/ObjectPrinting/PrintingConfig.cs b/ObjectPrinting/PrintingConfig.cs index a9e08211..e5785244 100644 --- a/ObjectPrinting/PrintingConfig.cs +++ b/ObjectPrinting/PrintingConfig.cs @@ -1,41 +1,199 @@ 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; +using ObjectPrinting.Interfaces; namespace ObjectPrinting { public class PrintingConfig { - public string PrintToString(TOwner obj) + private readonly HashSet FinalTypes = [ + typeof(string), typeof(DateTime), typeof(TimeSpan), typeof(Guid) + ]; + private readonly HashSet excludedTypes = []; + private readonly HashSet excludedMembers = []; + private readonly Dictionary> customMemberSerializers = []; + private readonly Dictionary> customTypeSerializers = []; + private int maxNestingDepth = 50; + + public PrintingConfig SetDepth(int depth) { - return PrintToString(obj, 0); + maxNestingDepth = depth; + return this; } - private string PrintToString(object obj, int nestingLevel) + // После долгих размышлений, как расширить FinalTypes, я только придумала дать возможность пользователю + // расширить нужные ему типы, которые посложнее примитивов + public PrintingConfig AddFinalTypes(IEnumerable types) { - //TODO apply configurations + FinalTypes.UnionWith(types); + return this; + } + + public PrintingConfig AddFinalType() + { + FinalTypes.Add(typeof(TFinalType)); + return this; + } + + public IPrintingConfig Printing() + { + return new TypePrintingConfig( + this, + customTypeSerializers); + } + + public IPrintingConfig Printing(Expression> memberSelector) + { + if (memberSelector.Body is not MemberExpression memberInfo) + throw new ArgumentException($"Expression '{memberSelector}' refers to a method, not a property/field."); + return new MemberPrintingConfig( + this, + customMemberSerializers, + memberInfo.Member); + } + + public PrintingConfig Excluding(Expression> memberSelector) + { + if (memberSelector.Body is not MemberExpression memberInfo) + throw new ArgumentException($"Expression '{memberSelector}' refers to a method, not a property/field."); + excludedMembers.Add(memberInfo.Member); + return this; + } + + internal PrintingConfig Excluding() + { + excludedTypes.Add(typeof(TPropType)); + return this; + } + + public string? PrintToString(TOwner obj) + { + return PrintToString(obj, 0, []); + } + + private string? PrintToString(object? obj, int nestingLevel, HashSet visitedObjects) + { + if (maxNestingDepth < nestingLevel) + return $"The maximum recursion depth {maxNestingDepth} has been reached"; + if (obj == null) - return "null" + Environment.NewLine; + return "null"; - var finalTypes = new[] + if (visitedObjects.Contains(obj)) + return "Cycling reference!"; + + var objType = obj.GetType(); + if (objType.IsPrimitive || FinalTypes.Contains(objType)) + { + if (customTypeSerializers.TryGetValue(objType, out var serializer)) + return serializer(obj); + + return obj is IFormattable formattable + ? formattable.ToString(null, CultureInfo.InvariantCulture) + : obj.ToString(); + } + + return obj switch { - typeof(int), typeof(double), typeof(float), typeof(string), - typeof(DateTime), typeof(TimeSpan) + IDictionary dictionary => PrintToStringIDictionary(dictionary, nestingLevel, visitedObjects), + IEnumerable enumerable => PrintToStringIEnumerable(enumerable, nestingLevel, visitedObjects), + _ => PrintToStringObject(obj, nestingLevel, visitedObjects) }; - if (finalTypes.Contains(obj.GetType())) - return obj + Environment.NewLine; + } + + private bool TryUseCustomSerializer(object value, MemberInfo memberInfo, out string? str) + { + str = null; + + if (customMemberSerializers.TryGetValue(memberInfo, out var lambda) || + customTypeSerializers.TryGetValue(memberInfo.GetMemberType(), out lambda)) + { + str = lambda(value); + return true; + } + + return false; + } + + private IEnumerable GetIncludedMembers(Type type) + { + var members = type.GetMembers() + .Where(m => m is PropertyInfo or FieldInfo) + .Where(m => !IsExcluded(m)); + return members; + } + + private bool IsExcluded(MemberInfo memberInfo) + { + return excludedMembers.Contains(memberInfo) || excludedTypes.Contains(memberInfo.GetMemberType()); + } - var identation = new string('\t', nestingLevel + 1); - var sb = new StringBuilder(); + private string PrintToStringObject(object obj, int nestingLevel, HashSet visitedObjects) + { + var indentation = new string('\t', nestingLevel + 1); + var builder = new StringBuilder(); var type = obj.GetType(); - sb.AppendLine(type.Name); - foreach (var propertyInfo in type.GetProperties()) + builder.Append(type.Name); + visitedObjects.Add(obj); + + foreach (var memberInfo in GetIncludedMembers(type)) { - sb.Append(identation + propertyInfo.Name + " = " + - PrintToString(propertyInfo.GetValue(obj), - nestingLevel + 1)); + var value = memberInfo.GetValue(obj); + var serializedStr = TryUseCustomSerializer(value, memberInfo, out var str) + ? str + : PrintToString(value, nestingLevel + 1, visitedObjects); + builder.Append('\n') + .Append(indentation) + .Append(memberInfo.Name) + .Append(" = ") + .Append(serializedStr); } - return sb.ToString(); + + visitedObjects.Remove(obj); + return builder.ToString(); + } + + private string PrintToStringIDictionary(IDictionary dictionary, int nestingLevel, HashSet visitedObjects) + { + var indentation = new string('\t', nestingLevel + 1); + var builder = new StringBuilder(); + builder.Append(dictionary.GetType().Name); + visitedObjects.Add(dictionary); + + foreach (DictionaryEntry item in dictionary) + builder.Append('\n') + .Append(indentation) + .Append(PrintToString(item.Key, nestingLevel + 1, visitedObjects)) + .Append(" = ") + .Append(PrintToString(item.Value, nestingLevel + 1, visitedObjects)); + + visitedObjects.Remove(dictionary); + return builder.ToString(); + } + + private string PrintToStringIEnumerable(IEnumerable collection, int nestingLevel, HashSet visitedObjects) + { + var indentation = new string('\t', nestingLevel + 1); + var builder = new StringBuilder(); + var index = 0; + builder.Append(collection.GetType().Name); + visitedObjects.Add(collection); + + foreach (var item in collection) + builder.Append('\n') + .Append(indentation) + .Append(index++) + .Append(" = ") + .Append(PrintToString(item, nestingLevel + 1, visitedObjects)); + + visitedObjects.Remove(collection); + return builder.ToString(); } } } \ No newline at end of file diff --git a/ObjectPrinting/PrintingConfigExtensions.cs b/ObjectPrinting/PrintingConfigExtensions.cs new file mode 100644 index 00000000..500d71fb --- /dev/null +++ b/ObjectPrinting/PrintingConfigExtensions.cs @@ -0,0 +1,25 @@ +using System; +using System.Globalization; +using ObjectPrinting.Interfaces; + +namespace ObjectPrinting; + +public static class PrintingConfigExtensions +{ + public static string PrintToString(this T obj, Func, PrintingConfig> config) + { + return config(ObjectPrinter.For()).PrintToString(obj); + } + + public static PrintingConfig TrimmedToLength(this IPrintingConfig config, int maxLen) + { + return config.Using(x => x == null ? "null" : x[..Math.Min(x.Length, maxLen)]); + } + + public static PrintingConfig SetCulture(this IPrintingConfig config, + CultureInfo culture) + where TPropType: IFormattable + { + return config.Using(x => x.ToString(null, culture)); + } +} \ 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/ObjectPrinterTests.cs b/ObjectPrinting/Tests/ObjectPrinterTests.cs new file mode 100644 index 00000000..684af196 --- /dev/null +++ b/ObjectPrinting/Tests/ObjectPrinterTests.cs @@ -0,0 +1,241 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Threading.Tasks; +using NUnit.Framework; +using VerifyNUnit; +using VerifyTests; + +namespace ObjectPrinting.Tests; + +[TestFixture] +public class ObjectPrinterTests +{ + private static readonly VerifySettings DefaultSettings = new(); + private Person person; + + [SetUp] + public void SetUp() + { + DefaultSettings.UseDirectory("Snapshots"); + person = new Person + { + Id = new Guid("2a5cacd7-a7a6-4c78-9b7c-c3377846cadd"), + Age = 10, + Name = "John Doe", + Height = 189.52, + DateOfBirth = new DateTime(1985, 9, 9) + }; + } + + [Test] + public Task PrintToString_AfterUsingDefault() + { + var serializedStr = person.PrintToString(); + + return Verifier.Verify(serializedStr, DefaultSettings); + } + + [Test] + public Task PrintToString_AfterUsingDefaultWithConfiguration() + { + var serializedStr = person.PrintToString( c => c.Excluding(p => p.Age)); + + return Verifier.Verify(serializedStr, DefaultSettings); + } + + [Test] + public Task PrintConfig_ShouldExcludeGivenType() + { + var config = ObjectPrinter.For() + .Excluding(); + + var serializedStr = config.PrintToString(person); + + return Verifier.Verify(serializedStr, DefaultSettings); + } + + [Test] + public Task PrintConfig_ShouldExcludeGivenMember() + { + var config = ObjectPrinter.For() + .Excluding(p => p.Addresses); + + var serializedStr = config.PrintToString(person); + + return Verifier.Verify(serializedStr, DefaultSettings); + } + + [Test] + public Task PrintToString_ShouldDisplayDictionaryCorrectly_AfterAttachingDirectoryToObject() + { + person.Addresses = new Dictionary + { + { 1, "London" }, + { 2, "New York" }, + { 3, "Moscow" } + }; + + var serializedStr = person.PrintToString(); + + return Verifier.Verify(serializedStr, DefaultSettings); + } + + [Test] + public Task PrintToString_ShouldDisplayCollectionCorrectly_AfterAttachingCollectionToObject() + { + person.Children = + [ + new Person { Name = "Natasha", Age = 8, DateOfBirth = new DateTime(2002, 9 , 9) }, + new Person { Name = "Pasha", Age = 8, DateOfBirth = new DateTime(2002, 9 , 9) }, + ]; + + var serializedStr = person.PrintToString(); + + return Verifier.Verify(serializedStr, DefaultSettings); + } + + [Test] + public Task PrintConfig_ShouldUseCustomSerializerForGivenType() + { + var config = ObjectPrinter.For() + .Printing().Using(x => $"{x} :^("); + + var serializedStr = config.PrintToString(person); + + return Verifier.Verify(serializedStr, DefaultSettings); + } + + [Test] + public Task PrintConfig_ShouldUseCustomSerializerForGivenMember() + { + var config = ObjectPrinter.For() + .Printing(p => p.DateOfBirth).Using(x => x.ToString("dd/MM/yyyy", CultureInfo.InvariantCulture)); + + var serializedStr = config.PrintToString(person); + + return Verifier.Verify(serializedStr, DefaultSettings); + } + + [Test] + public Task PrintConfig_ShouldUseGivenCultureForGivenType() + { + var config = ObjectPrinter.For() + .Printing().SetCulture(new CultureInfo("ru-RU")); + + var serializedStr = config.PrintToString(person); + + return Verifier.Verify(serializedStr, DefaultSettings); + } + + [Test] + public Task PrintConfig_ShouldUseGivenCultureForGivenMember() + { + var config = ObjectPrinter.For() + .Printing(p => p.Height).SetCulture(new CultureInfo("ru-RU")); + + var serializedStr = config.PrintToString(person); + + return Verifier.Verify(serializedStr, DefaultSettings); + } + + [Test] + public Task PrintConfig_ShouldTrimStringType() + { + var config = ObjectPrinter.For() + .Printing().TrimmedToLength(1); + + var serializedStr = config.PrintToString(person); + + return Verifier.Verify(serializedStr, DefaultSettings); + } + + [Test] + public Task PrintConfig_ShouldTrimStringMember() + { + var config = ObjectPrinter.For() + .Printing(p => p.Name).TrimmedToLength(2); + + var serializedStr = config.PrintToString(person); + + return Verifier.Verify(serializedStr, DefaultSettings); + } + + [Test] + public Task PrintToString_ShouldDetectCircularReferences() + { + var father = new Person + { + Name = "Pavel Doe", + Age = 68, + DateOfBirth = new DateTime(1954, 9, 9), + Father = person + }; + person.Father = father; + + var serializedStr = person.PrintToString(); + + return Verifier.Verify(serializedStr, DefaultSettings); + } + + [Test] + public Task PrintToString_ShouldDisplayDirectoryCorrectly() + { + var dictionary = new Dictionary + { + { 1, person }, + { 2, person } + }; + + var serializedStr = dictionary.PrintToString(); + + return Verifier.Verify(serializedStr, DefaultSettings); + } + + [Test] + public Task PrintToString_ShouldDisplayCollectionCorrectly() + { + var collection = new List + { + person, + person + }; + + var serializedStr = collection.PrintToString(); + + return Verifier.Verify(serializedStr, DefaultSettings); + } + + [Test] + public Task PrintConfig_ShouldApplyMultipleConfigurationsCorrectly() + { + var config = ObjectPrinter.For() + .Excluding() + .Printing().Using(x => $"{x} :^(") + .Printing().SetCulture(new CultureInfo("ru-RU")) + .Printing(p => p.DateOfBirth).Using(x => x.ToString("dd/MM/yyyy", CultureInfo.InvariantCulture)) + .Printing(p => p.Name).TrimmedToLength(5) + .Excluding(p => p.Addresses); + + var serializedStr = config.PrintToString(person); + + return Verifier.Verify(serializedStr, DefaultSettings); + } + + [Test] + public Task PrintConfig_ShouldApplyConfigurationToChildrenObject() + { + person.Children = + [ + new Person { Name = "Natasha", Age = 8, DateOfBirth = new DateTime(2002, 9 , 9) }, + new Person { Name = "Pasha", Age = 8, DateOfBirth = new DateTime(2002, 9 , 9) }, + ]; + var config = ObjectPrinter.For() + .Excluding(); + + var serializedStr = config.PrintToString(person); + + return Verifier.Verify(serializedStr, DefaultSettings); + } + +} \ No newline at end of file diff --git a/ObjectPrinting/Tests/Person.cs b/ObjectPrinting/Tests/Person.cs index f9555955..7da37aed 100644 --- a/ObjectPrinting/Tests/Person.cs +++ b/ObjectPrinting/Tests/Person.cs @@ -1,4 +1,6 @@ using System; +using System.Collections.Generic; +using System.Drawing; namespace ObjectPrinting.Tests { @@ -8,5 +10,9 @@ public class Person public string Name { get; set; } public double Height { get; set; } public int Age { get; set; } + public List Children { get; set; } + public Person Father { get; set; } + public DateTime DateOfBirth; + public Dictionary Addresses; } } \ No newline at end of file diff --git a/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintConfig_ShouldApplyConfigurationToChildrenObject.verified.txt b/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintConfig_ShouldApplyConfigurationToChildrenObject.verified.txt new file mode 100644 index 00000000..f4603be9 --- /dev/null +++ b/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintConfig_ShouldApplyConfigurationToChildrenObject.verified.txt @@ -0,0 +1,24 @@ +Person + Name = John Doe + Height = 189.52 + Age = 10 + Children = List`1 + 0 = Person + Name = Natasha + Height = 0 + Age = 8 + Children = null + Father = null + DateOfBirth = 09/09/2002 00:00:00 + Addresses = null + 1 = Person + Name = Pasha + Height = 0 + Age = 8 + Children = null + Father = null + DateOfBirth = 09/09/2002 00:00:00 + Addresses = null + Father = null + DateOfBirth = 09/09/1985 00:00:00 + Addresses = null \ No newline at end of file diff --git a/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintConfig_ShouldApplyMultipleConfigurationsCorrectly.verified.txt b/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintConfig_ShouldApplyMultipleConfigurationsCorrectly.verified.txt new file mode 100644 index 00000000..d64616ea --- /dev/null +++ b/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintConfig_ShouldApplyMultipleConfigurationsCorrectly.verified.txt @@ -0,0 +1,7 @@ +Person + Name = John + Height = 189,52 + Age = 10 :^( + Children = null + Father = null + DateOfBirth = 09/09/1985 \ No newline at end of file diff --git a/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintConfig_ShouldExcludeGivenMember.verified.txt b/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintConfig_ShouldExcludeGivenMember.verified.txt new file mode 100644 index 00000000..a1f81c20 --- /dev/null +++ b/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintConfig_ShouldExcludeGivenMember.verified.txt @@ -0,0 +1,8 @@ +Person + Id = 2a5cacd7-a7a6-4c78-9b7c-c3377846cadd + Name = John Doe + Height = 189.52 + Age = 10 + Children = null + Father = null + DateOfBirth = 09/09/1985 00:00:00 \ No newline at end of file diff --git a/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintConfig_ShouldExcludeGivenType.verified.txt b/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintConfig_ShouldExcludeGivenType.verified.txt new file mode 100644 index 00000000..09d6a068 --- /dev/null +++ b/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintConfig_ShouldExcludeGivenType.verified.txt @@ -0,0 +1,8 @@ +Person + Name = John Doe + Height = 189.52 + Age = 10 + Children = null + Father = null + DateOfBirth = 09/09/1985 00:00:00 + Addresses = null \ No newline at end of file diff --git a/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintConfig_ShouldTrimStringMember.verified.txt b/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintConfig_ShouldTrimStringMember.verified.txt new file mode 100644 index 00000000..b74b67f8 --- /dev/null +++ b/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintConfig_ShouldTrimStringMember.verified.txt @@ -0,0 +1,9 @@ +Person + Id = 2a5cacd7-a7a6-4c78-9b7c-c3377846cadd + Name = Jo + Height = 189.52 + Age = 10 + Children = null + Father = null + DateOfBirth = 09/09/1985 00:00:00 + Addresses = null \ No newline at end of file diff --git a/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintConfig_ShouldTrimStringType.verified.txt b/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintConfig_ShouldTrimStringType.verified.txt new file mode 100644 index 00000000..f2d9c3dd --- /dev/null +++ b/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintConfig_ShouldTrimStringType.verified.txt @@ -0,0 +1,9 @@ +Person + Id = 2a5cacd7-a7a6-4c78-9b7c-c3377846cadd + Name = J + Height = 189.52 + Age = 10 + Children = null + Father = null + DateOfBirth = 09/09/1985 00:00:00 + Addresses = null \ No newline at end of file diff --git a/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintConfig_ShouldUseCustomSerializerForGivenMember.verified.txt b/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintConfig_ShouldUseCustomSerializerForGivenMember.verified.txt new file mode 100644 index 00000000..a636d819 --- /dev/null +++ b/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintConfig_ShouldUseCustomSerializerForGivenMember.verified.txt @@ -0,0 +1,9 @@ +Person + Id = 2a5cacd7-a7a6-4c78-9b7c-c3377846cadd + Name = John Doe + Height = 189.52 + Age = 10 + Children = null + Father = null + DateOfBirth = 09/09/1985 + Addresses = null \ No newline at end of file diff --git a/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintConfig_ShouldUseCustomSerializerForGivenType.verified.txt b/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintConfig_ShouldUseCustomSerializerForGivenType.verified.txt new file mode 100644 index 00000000..0bb0bb48 --- /dev/null +++ b/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintConfig_ShouldUseCustomSerializerForGivenType.verified.txt @@ -0,0 +1,9 @@ +Person + Id = 2a5cacd7-a7a6-4c78-9b7c-c3377846cadd + Name = John Doe + Height = 189.52 + Age = 10 :^( + Children = null + Father = null + DateOfBirth = 09/09/1985 00:00:00 + Addresses = null \ No newline at end of file diff --git a/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintConfig_ShouldUseGivenCultureForGivenMember.verified.txt b/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintConfig_ShouldUseGivenCultureForGivenMember.verified.txt new file mode 100644 index 00000000..dba54eb7 --- /dev/null +++ b/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintConfig_ShouldUseGivenCultureForGivenMember.verified.txt @@ -0,0 +1,9 @@ +Person + Id = 2a5cacd7-a7a6-4c78-9b7c-c3377846cadd + Name = John Doe + Height = 189,52 + Age = 10 + Children = null + Father = null + DateOfBirth = 09/09/1985 00:00:00 + Addresses = null \ No newline at end of file diff --git a/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintConfig_ShouldUseGivenCultureForGivenType.verified.txt b/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintConfig_ShouldUseGivenCultureForGivenType.verified.txt new file mode 100644 index 00000000..dba54eb7 --- /dev/null +++ b/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintConfig_ShouldUseGivenCultureForGivenType.verified.txt @@ -0,0 +1,9 @@ +Person + Id = 2a5cacd7-a7a6-4c78-9b7c-c3377846cadd + Name = John Doe + Height = 189,52 + Age = 10 + Children = null + Father = null + DateOfBirth = 09/09/1985 00:00:00 + Addresses = null \ No newline at end of file diff --git a/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_AfterUsingDefault.verified.txt b/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_AfterUsingDefault.verified.txt new file mode 100644 index 00000000..ccf41ae0 --- /dev/null +++ b/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_AfterUsingDefault.verified.txt @@ -0,0 +1,9 @@ +Person + Id = 2a5cacd7-a7a6-4c78-9b7c-c3377846cadd + Name = John Doe + Height = 189.52 + Age = 10 + Children = null + Father = null + DateOfBirth = 09/09/1985 00:00:00 + Addresses = null \ No newline at end of file diff --git a/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_AfterUsingDefaultWithConfiguration.verified.txt b/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_AfterUsingDefaultWithConfiguration.verified.txt new file mode 100644 index 00000000..a22fc5c8 --- /dev/null +++ b/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_AfterUsingDefaultWithConfiguration.verified.txt @@ -0,0 +1,8 @@ +Person + Id = 2a5cacd7-a7a6-4c78-9b7c-c3377846cadd + Name = John Doe + Height = 189.52 + Children = null + Father = null + DateOfBirth = 09/09/1985 00:00:00 + Addresses = null \ No newline at end of file diff --git a/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_ShouldDetectCircularReferences.verified.txt b/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_ShouldDetectCircularReferences.verified.txt new file mode 100644 index 00000000..219bb27e --- /dev/null +++ b/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_ShouldDetectCircularReferences.verified.txt @@ -0,0 +1,17 @@ +Person + Id = 2a5cacd7-a7a6-4c78-9b7c-c3377846cadd + Name = John Doe + Height = 189.52 + Age = 10 + Children = null + Father = Person + Id = 00000000-0000-0000-0000-000000000000 + Name = Pavel Doe + Height = 0 + Age = 68 + Children = null + Father = Cycling reference! + DateOfBirth = 09/09/1954 00:00:00 + Addresses = null + DateOfBirth = 09/09/1985 00:00:00 + Addresses = null \ No newline at end of file diff --git a/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_ShouldDisplayCollectionCorrectly.verified.txt b/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_ShouldDisplayCollectionCorrectly.verified.txt new file mode 100644 index 00000000..3c649101 --- /dev/null +++ b/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_ShouldDisplayCollectionCorrectly.verified.txt @@ -0,0 +1,19 @@ +List`1 + 0 = Person + Id = 2a5cacd7-a7a6-4c78-9b7c-c3377846cadd + Name = John Doe + Height = 189.52 + Age = 10 + Children = null + Father = null + DateOfBirth = 09/09/1985 00:00:00 + Addresses = null + 1 = Person + Id = 2a5cacd7-a7a6-4c78-9b7c-c3377846cadd + Name = John Doe + Height = 189.52 + Age = 10 + Children = null + Father = null + DateOfBirth = 09/09/1985 00:00:00 + Addresses = null \ No newline at end of file diff --git a/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_ShouldDisplayCollectionCorrectly_AfterAttachingCollectionToObject.verified.txt b/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_ShouldDisplayCollectionCorrectly_AfterAttachingCollectionToObject.verified.txt new file mode 100644 index 00000000..cc2c8b96 --- /dev/null +++ b/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_ShouldDisplayCollectionCorrectly_AfterAttachingCollectionToObject.verified.txt @@ -0,0 +1,27 @@ +Person + Id = 2a5cacd7-a7a6-4c78-9b7c-c3377846cadd + Name = John Doe + Height = 189.52 + Age = 10 + Children = List`1 + 0 = Person + Id = 00000000-0000-0000-0000-000000000000 + Name = Natasha + Height = 0 + Age = 8 + Children = null + Father = null + DateOfBirth = 09/09/2002 00:00:00 + Addresses = null + 1 = Person + Id = 00000000-0000-0000-0000-000000000000 + Name = Pasha + Height = 0 + Age = 8 + Children = null + Father = null + DateOfBirth = 09/09/2002 00:00:00 + Addresses = null + Father = null + DateOfBirth = 09/09/1985 00:00:00 + Addresses = null \ No newline at end of file diff --git a/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_ShouldDisplayDictionaryCorrectly_AfterAttachingDirectoryToObject.verified.txt b/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_ShouldDisplayDictionaryCorrectly_AfterAttachingDirectoryToObject.verified.txt new file mode 100644 index 00000000..44c1b6e5 --- /dev/null +++ b/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_ShouldDisplayDictionaryCorrectly_AfterAttachingDirectoryToObject.verified.txt @@ -0,0 +1,12 @@ +Person + Id = 2a5cacd7-a7a6-4c78-9b7c-c3377846cadd + Name = John Doe + Height = 189.52 + Age = 10 + Children = null + Father = null + DateOfBirth = 09/09/1985 00:00:00 + Addresses = Dictionary`2 + 1 = London + 2 = New York + 3 = Moscow \ No newline at end of file diff --git a/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_ShouldDisplayDirectoryCorrectly.verified.txt b/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_ShouldDisplayDirectoryCorrectly.verified.txt new file mode 100644 index 00000000..cc9d439b --- /dev/null +++ b/ObjectPrinting/Tests/Snapshots/ObjectPrinterTests.PrintToString_ShouldDisplayDirectoryCorrectly.verified.txt @@ -0,0 +1,19 @@ +Dictionary`2 + 1 = Person + Id = 2a5cacd7-a7a6-4c78-9b7c-c3377846cadd + Name = John Doe + Height = 189.52 + Age = 10 + Children = null + Father = null + DateOfBirth = 09/09/1985 00:00:00 + Addresses = null + 2 = Person + Id = 2a5cacd7-a7a6-4c78-9b7c-c3377846cadd + Name = John Doe + Height = 189.52 + Age = 10 + Children = null + Father = null + DateOfBirth = 09/09/1985 00:00:00 + Addresses = null \ No newline at end of file diff --git a/ObjectPrinting/TypePrintingConfig.cs b/ObjectPrinting/TypePrintingConfig.cs new file mode 100644 index 00000000..723eb3c9 --- /dev/null +++ b/ObjectPrinting/TypePrintingConfig.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using ObjectPrinting.Interfaces; + +namespace ObjectPrinting; + +public class TypePrintingConfig : IPrintingConfig +{ + private readonly PrintingConfig parent; + private readonly Dictionary> customSerializers; + + public TypePrintingConfig(PrintingConfig parent, + Dictionary> customSerializers) + { + this.parent = parent; + this.customSerializers = customSerializers; + } + + public PrintingConfig Using(Func print) + { + customSerializers[typeof(TType)] = obj => print((TType)obj); + return parent; + } +} \ No newline at end of file diff --git a/fluent-api.sln.DotSettings b/fluent-api.sln.DotSettings index 135b83ec..53fe49b2 100644 --- a/fluent-api.sln.DotSettings +++ b/fluent-api.sln.DotSettings @@ -1,6 +1,9 @@  <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb_AaBb" /> + <Policy><Descriptor Staticness="Instance" AccessRightKinds="Private" Description="Instance fields (private)"><ElementKinds><Kind Name="FIELD" /><Kind Name="READONLY_FIELD" /></ElementKinds></Descriptor><Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="" Suffix="" Style="aaBb" /></Policy> + <Policy><Descriptor Staticness="Any" AccessRightKinds="Any" Description="Types and namespaces"><ElementKinds><Kind Name="NAMESPACE" /><Kind Name="CLASS" /><Kind Name="STRUCT" /><Kind Name="ENUM" /><Kind Name="DELEGATE" /></ElementKinds></Descriptor><Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="" Suffix="" Style="AaBb_AaBb" /></Policy> + True True True Imported 10.10.2016