diff --git a/ObjectPrinting.Tests/ForVerifier/ObjectPrinterTests.Demo.verified.txt b/ObjectPrinting.Tests/ForVerifier/ObjectPrinterTests.Demo.verified.txt new file mode 100644 index 00000000..290414ba --- /dev/null +++ b/ObjectPrinting.Tests/ForVerifier/ObjectPrinterTests.Demo.verified.txt @@ -0,0 +1,48 @@ +Person + Name = Dima + Height = 176 + Age = Hidden + BirthDate = 7/27/1985 12:00:00 AM + Husband = null + Wife = null + HomeworksCompleted = + Testi + Tag c + Markd + Objec + Friends = + Person + Name = Nikit + Height = 0 + Age = Hidden + BirthDate = 1/1/0001 12:00:00 AM + Husband = null + Wife = null + HomeworksCompleted = null + Friends = null + EmergensyList = null + LastName = null + ToExclude = null + + Person + Name = Pasha + Height = 0 + Age = Hidden + BirthDate = 1/1/0001 12:00:00 AM + Husband = null + Wife = null + HomeworksCompleted = null + Friends = null + EmergensyList = null + LastName = null + ToExclude = null + + EmergensyList = + key = wife + value = 8-800 + key = fathe + value = 3-10- + key = mothe + value = 03 + LastName = null + ToExclude = null diff --git a/ObjectPrinting.Tests/ForVerifier/ObjectPrinterTests.Excluding_ShouldExcludeConcreteProperty.verified.txt b/ObjectPrinting.Tests/ForVerifier/ObjectPrinterTests.Excluding_ShouldExcludeConcreteProperty.verified.txt new file mode 100644 index 00000000..ba1ad4d5 --- /dev/null +++ b/ObjectPrinting.Tests/ForVerifier/ObjectPrinterTests.Excluding_ShouldExcludeConcreteProperty.verified.txt @@ -0,0 +1,48 @@ +Person + Name = Dima + Height = 176 + Age = 39 + BirthDate = 27.07.1985 0:00:00 + Husband = null + Wife = null + HomeworksCompleted = + Testing + Tag cloud + Markdown + Object Printer + Friends = + Person + Name = Nikita + Height = 0 + Age = 0 + BirthDate = 01.01.0001 0:00:00 + Husband = null + Wife = null + HomeworksCompleted = null + Friends = null + EmergensyList = null + LastName = null + ToExclude = null + + Person + Name = Pasha + Height = 0 + Age = 0 + BirthDate = 01.01.0001 0:00:00 + Husband = null + Wife = null + HomeworksCompleted = null + Friends = null + EmergensyList = null + LastName = null + ToExclude = null + + EmergensyList = + key = wife + value = 8-800-5-5-5-3-5-3-5 + key = father + value = 3-10-10-10 + key = mother + value = 03 + LastName = null + ToExclude = null diff --git a/ObjectPrinting.Tests/ForVerifier/ObjectPrinterTests.Excluding_ShouldExcludePropertyOfType.verified.txt b/ObjectPrinting.Tests/ForVerifier/ObjectPrinterTests.Excluding_ShouldExcludePropertyOfType.verified.txt new file mode 100644 index 00000000..049bc8c7 --- /dev/null +++ b/ObjectPrinting.Tests/ForVerifier/ObjectPrinterTests.Excluding_ShouldExcludePropertyOfType.verified.txt @@ -0,0 +1,48 @@ +Person + Id = 3f2504e0-4f89-11d3-9a0c-0305e82c3301 + Height = 176 + Age = 39 + BirthDate = 27.07.1985 0:00:00 + Husband = null + Wife = null + HomeworksCompleted = + + + + + Friends = + Person + Id = 00000000-0000-0000-0000-000000000000 + Height = 0 + Age = 0 + BirthDate = 01.01.0001 0:00:00 + Husband = null + Wife = null + HomeworksCompleted = null + Friends = null + EmergensyList = null + LastName = null + ToExclude = null + + Person + Id = 00000000-0000-0000-0000-000000000000 + Height = 0 + Age = 0 + BirthDate = 01.01.0001 0:00:00 + Husband = null + Wife = null + HomeworksCompleted = null + Friends = null + EmergensyList = null + LastName = null + ToExclude = null + + EmergensyList = + key = + value = + key = + value = + key = + value = + LastName = null + ToExclude = null diff --git a/ObjectPrinting.Tests/ForVerifier/ObjectPrinterTests.ObjectPrinter_ShouldFindLoop.verified.txt b/ObjectPrinting.Tests/ForVerifier/ObjectPrinterTests.ObjectPrinter_ShouldFindLoop.verified.txt new file mode 100644 index 00000000..9c118afb --- /dev/null +++ b/ObjectPrinting.Tests/ForVerifier/ObjectPrinterTests.ObjectPrinter_ShouldFindLoop.verified.txt @@ -0,0 +1,2 @@ +Foo + Self = Loop found diff --git a/ObjectPrinting.Tests/ForVerifier/ObjectPrinterTests.SetCulture_ShouldSetCulture.verified.txt b/ObjectPrinting.Tests/ForVerifier/ObjectPrinterTests.SetCulture_ShouldSetCulture.verified.txt new file mode 100644 index 00000000..bbaffb82 --- /dev/null +++ b/ObjectPrinting.Tests/ForVerifier/ObjectPrinterTests.SetCulture_ShouldSetCulture.verified.txt @@ -0,0 +1,51 @@ +Person + Id = 3f2504e0-4f89-11d3-9a0c-0305e82c3301 + Name = Dima + Height = 176 + Age = 39 + BirthDate = 7/27/1985 12:00:00 AM + Husband = null + Wife = null + HomeworksCompleted = + Testing + Tag cloud + Markdown + Object Printer + Friends = + Person + Id = 00000000-0000-0000-0000-000000000000 + Name = Nikita + Height = 0 + Age = 0 + BirthDate = 1/1/0001 12:00:00 AM + Husband = null + Wife = null + HomeworksCompleted = null + Friends = null + EmergensyList = null + LastName = null + ToExclude = null + + Person + Id = 00000000-0000-0000-0000-000000000000 + Name = Pasha + Height = 0 + Age = 0 + BirthDate = 1/1/0001 12:00:00 AM + Husband = null + Wife = null + HomeworksCompleted = null + Friends = null + EmergensyList = null + LastName = null + ToExclude = null + + EmergensyList = + key = wife + value = 8-800-5-5-5-3-5-3-5 + key = father + value = 3-10-10-10 + key = mother + value = 03 + LastName = null + ToExclude = null diff --git a/ObjectPrinting.Tests/ForVerifier/ObjectPrinterTests.TrimmedToLength_ShouldTrimStringType_maxLen=10.verified.txt b/ObjectPrinting.Tests/ForVerifier/ObjectPrinterTests.TrimmedToLength_ShouldTrimStringType_maxLen=10.verified.txt new file mode 100644 index 00000000..a64cde8b --- /dev/null +++ b/ObjectPrinting.Tests/ForVerifier/ObjectPrinterTests.TrimmedToLength_ShouldTrimStringType_maxLen=10.verified.txt @@ -0,0 +1,51 @@ +Person + Id = 3f2504e0-4f89-11d3-9a0c-0305e82c3301 + Name = Dima + Height = 176 + Age = 39 + BirthDate = 27.07.1985 0:00:00 + Husband = null + Wife = null + HomeworksCompleted = + Testing + Tag cloud + Markdown + Object Pri + Friends = + Person + Id = 00000000-0000-0000-0000-000000000000 + Name = Nikita + Height = 0 + Age = 0 + BirthDate = 01.01.0001 0:00:00 + Husband = null + Wife = null + HomeworksCompleted = null + Friends = null + EmergensyList = null + LastName = null + ToExclude = null + + Person + Id = 00000000-0000-0000-0000-000000000000 + Name = Pasha + Height = 0 + Age = 0 + BirthDate = 01.01.0001 0:00:00 + Husband = null + Wife = null + HomeworksCompleted = null + Friends = null + EmergensyList = null + LastName = null + ToExclude = null + + EmergensyList = + key = wife + value = 8-800-5-5- + key = father + value = 3-10-10-10 + key = mother + value = 03 + LastName = null + ToExclude = null diff --git a/ObjectPrinting.Tests/ForVerifier/ObjectPrinterTests.TrimmedToLength_ShouldTrimStringType_maxLen=3.verified.txt b/ObjectPrinting.Tests/ForVerifier/ObjectPrinterTests.TrimmedToLength_ShouldTrimStringType_maxLen=3.verified.txt new file mode 100644 index 00000000..ab25797f --- /dev/null +++ b/ObjectPrinting.Tests/ForVerifier/ObjectPrinterTests.TrimmedToLength_ShouldTrimStringType_maxLen=3.verified.txt @@ -0,0 +1,51 @@ +Person + Id = 3f2504e0-4f89-11d3-9a0c-0305e82c3301 + Name = Dim + Height = 176 + Age = 39 + BirthDate = 27.07.1985 0:00:00 + Husband = null + Wife = null + HomeworksCompleted = + Tes + Tag + Mar + Obj + Friends = + Person + Id = 00000000-0000-0000-0000-000000000000 + Name = Nik + Height = 0 + Age = 0 + BirthDate = 01.01.0001 0:00:00 + Husband = null + Wife = null + HomeworksCompleted = null + Friends = null + EmergensyList = null + LastName = null + ToExclude = null + + Person + Id = 00000000-0000-0000-0000-000000000000 + Name = Pas + Height = 0 + Age = 0 + BirthDate = 01.01.0001 0:00:00 + Husband = null + Wife = null + HomeworksCompleted = null + Friends = null + EmergensyList = null + LastName = null + ToExclude = null + + EmergensyList = + key = wif + value = 8-8 + key = fat + value = 3-1 + key = mot + value = 03 + LastName = null + ToExclude = null diff --git a/ObjectPrinting.Tests/ForVerifier/ObjectPrinterTests.Using_ShouldSetPrinterForProperty.verified.txt b/ObjectPrinting.Tests/ForVerifier/ObjectPrinterTests.Using_ShouldSetPrinterForProperty.verified.txt new file mode 100644 index 00000000..79b6349d --- /dev/null +++ b/ObjectPrinting.Tests/ForVerifier/ObjectPrinterTests.Using_ShouldSetPrinterForProperty.verified.txt @@ -0,0 +1,51 @@ +Person + Id = 3f2504e0-4f89-11d3-9a0c-0305e82c3301 + Name = XX + Height = 176 + Age = 39 + BirthDate = 27.07.1985 0:00:00 + Husband = null + Wife = null + HomeworksCompleted = + XX + XX + XX + XX + Friends = + Person + Id = 00000000-0000-0000-0000-000000000000 + Name = XX + Height = 0 + Age = 0 + BirthDate = 01.01.0001 0:00:00 + Husband = null + Wife = null + HomeworksCompleted = null + Friends = null + EmergensyList = null + LastName = null + ToExclude = null + + Person + Id = 00000000-0000-0000-0000-000000000000 + Name = XX + Height = 0 + Age = 0 + BirthDate = 01.01.0001 0:00:00 + Husband = null + Wife = null + HomeworksCompleted = null + Friends = null + EmergensyList = null + LastName = null + ToExclude = null + + EmergensyList = + key = XX + value = XX + key = XX + value = XX + key = XX + value = XX + LastName = null + ToExclude = null diff --git a/ObjectPrinting.Tests/ForVerifier/ObjectPrinterTests.Using_ShouldSetPrinterForType.verified.txt b/ObjectPrinting.Tests/ForVerifier/ObjectPrinterTests.Using_ShouldSetPrinterForType.verified.txt new file mode 100644 index 00000000..40896106 --- /dev/null +++ b/ObjectPrinting.Tests/ForVerifier/ObjectPrinterTests.Using_ShouldSetPrinterForType.verified.txt @@ -0,0 +1,51 @@ +Person + Id = 3f2504e0-4f89-11d3-9a0c-0305e82c3301 + Name = Dima + Height = 176 + Age = XX + BirthDate = 27.07.1985 0:00:00 + Husband = null + Wife = null + HomeworksCompleted = + Testing + Tag cloud + Markdown + Object Printer + Friends = + Person + Id = 00000000-0000-0000-0000-000000000000 + Name = Nikita + Height = 0 + Age = XX + BirthDate = 01.01.0001 0:00:00 + Husband = null + Wife = null + HomeworksCompleted = null + Friends = null + EmergensyList = null + LastName = null + ToExclude = null + + Person + Id = 00000000-0000-0000-0000-000000000000 + Name = Pasha + Height = 0 + Age = XX + BirthDate = 01.01.0001 0:00:00 + Husband = null + Wife = null + HomeworksCompleted = null + Friends = null + EmergensyList = null + LastName = null + ToExclude = null + + EmergensyList = + key = wife + value = 8-800-5-5-5-3-5-3-5 + key = father + value = 3-10-10-10 + key = mother + value = 03 + LastName = null + ToExclude = null diff --git a/ObjectPrinting.Tests/ObjectPrinterTests.cs b/ObjectPrinting.Tests/ObjectPrinterTests.cs new file mode 100644 index 00000000..44149875 --- /dev/null +++ b/ObjectPrinting.Tests/ObjectPrinterTests.cs @@ -0,0 +1,149 @@ +using System.Globalization; + +namespace ObjectPrinting.Tests +{ + [TestFixture] + public class ObjectPrinterTests + { + private static readonly VerifySettings DefaultSettings = new(); + private Person person; + private static Task Verify(string printedObject) => Verifier.Verify(printedObject, DefaultSettings); + + [OneTimeSetUp] + public void OneTimeSetup() + { + DefaultSettings.UseDirectory("ForVerifier"); + person = new Person + { + Id = new Guid("3f2504e0-4f89-11d3-9a0c-0305e82c3301"), + Age = 39, + Name = "Dima", + Height = 176.0, + BirthDate = new DateTime(1985, 07, 27) + }; + + var homeworks = new List() + { + "Testing", + "Tag cloud", + "Markdown", + "Object Printer" + }; + person.HomeworksCompleted = homeworks; + + var friends = new[] + { + new Person() { Name = "Nikita" }, + new Person() { Name = "Pasha" } + }; + person.Friends = friends; + + var emergencyCallList = new Dictionary() + { + {"wife","8-800-5-5-5-3-5-3-5"}, + {"father", "3-10-10-10"}, + {"mother", "03"} + }; + person.EmergensyList = emergencyCallList; + } + + [Test] + public Task Excluding_ShouldExcludePropertyOfType() + { + var result = ObjectPrinter.For() + .Excluding() + .PrintToString(person); + + return Verify(result); + } + + [Test] + public Task Excluding_ShouldExcludeConcreteProperty() + { + var result = ObjectPrinter.For() + .Excluding(p => p.ToExclude) + .Excluding(p => p.Id) + .PrintToString(person); + + return Verify(result); + } + + [Test] + public Task Using_ShouldSetPrinterForType() + { + var result = ObjectPrinter.For() + .Printing().Using(_ => "XX") + .PrintToString(person); + + return Verify(result); + } + + [Test] + public Task Using_ShouldSetPrinterForProperty() + { + var result = ObjectPrinter.For() + .Printing(p => p.Name).Using(_ => "XX") + .PrintToString(person); + + return Verify(result); + } + + [Test] + public Task SetCulture_ShouldSetCulture() + { + var result = ObjectPrinter.For() + .Printing().SetCulture(new CultureInfo("en")) + .PrintToString(person); + + return Verify(result); + } + + [TestCase(10, TestName = "Print original string when its length smaller than needed") ] + [TestCase(3, TestName = "Print trimmed string in right way")] + public Task TrimmedToLength_ShouldTrimStringType(int maxLen) + { + var result = ObjectPrinter.For() + .Printing().TrimmedToLength(maxLen) + .PrintToString(person); + + return Verify(result); + } + + private class Foo + { + public Foo Self { get; set; } + } + + [Test] + public Task ObjectPrinter_ShouldFindLoop() + { + var foo = new Foo(); + foo.Self = foo; + + var result = foo.PrintToString(); + + return Verify(result); + } + + [Test] + public Task Demo() + { + var result = ObjectPrinter.For() + //1. + .Excluding() + //2. + .Printing().Using(_ => "XX") + //3. + .Printing().SetCulture(new CultureInfo("en")) + //4. + .Printing(p => p.Age).Using(_ => "Hidden") + //5. ( ) + .Printing().TrimmedToLength(5) + //6. + .Excluding(p => p.ToExclude) + .PrintToString(person); + + return Verify(result); + } + } +} \ No newline at end of file diff --git a/ObjectPrinting.Tests/ObjectPrinting.Tests.csproj b/ObjectPrinting.Tests/ObjectPrinting.Tests.csproj new file mode 100644 index 00000000..23528238 --- /dev/null +++ b/ObjectPrinting.Tests/ObjectPrinting.Tests.csproj @@ -0,0 +1,33 @@ + + + + net8.0 + enable + enable + + false + true + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ObjectPrinting.Tests/Person.cs b/ObjectPrinting.Tests/Person.cs new file mode 100644 index 00000000..254e305c --- /dev/null +++ b/ObjectPrinting.Tests/Person.cs @@ -0,0 +1,21 @@ +using System; +using System.Runtime.InteropServices; + +namespace ObjectPrinting.Tests +{ + public class Person + { + public string LastName; + public string ToExclude; + public Guid Id { get; set; } + public string Name { get; set; } + public double Height { get; set; } + public int Age { get; set; } + public DateTime BirthDate { get; set; } + public Person Husband { get; set; } + public Person Wife { get; set; } + public List HomeworksCompleted { get; set; } + public Person[] Friends { get; set; } + public Dictionary EmergensyList { get; set; } + } +} \ No newline at end of file diff --git a/ObjectPrinting/FinalTypes.cs b/ObjectPrinting/FinalTypes.cs new file mode 100644 index 00000000..80842774 --- /dev/null +++ b/ObjectPrinting/FinalTypes.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ObjectPrinting +{ + public class FinalTypes + { + public static readonly HashSet Set = + [ + typeof(int), + typeof(double), + typeof(float), + typeof(string), + typeof(DateTime), + typeof(TimeSpan), + typeof(Guid) + ]; + } +} diff --git a/ObjectPrinting/MemberInfoExtensions.cs b/ObjectPrinting/MemberInfoExtensions.cs new file mode 100644 index 00000000..773da682 --- /dev/null +++ b/ObjectPrinting/MemberInfoExtensions.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; + +namespace ObjectPrinting +{ + public static class MemberInfoExtensions + { public static object GetValue(this MemberInfo memberInfo, object forObject) + { + return memberInfo.MemberType switch + { + MemberTypes.Field => ((FieldInfo)memberInfo).GetValue(forObject), + MemberTypes.Property => ((PropertyInfo)memberInfo).GetValue(forObject), + _ => throw new NotSupportedException($"Unsupported member type {memberInfo.MemberType}"), + }; + } + } +} diff --git a/ObjectPrinting/ObjectExtensions.cs b/ObjectPrinting/ObjectExtensions.cs new file mode 100644 index 00000000..0d140304 --- /dev/null +++ b/ObjectPrinting/ObjectExtensions.cs @@ -0,0 +1,18 @@ +using System; + +namespace ObjectPrinting +{ + + public static class ObjectExtensions + { + public static string PrintToString(this T obj) + { + return ObjectPrinter.For().PrintToString(obj); + } + + public static string PrintToString(this T obj, Func, PrintingConfig> config) + { + return config(ObjectPrinter.For()).PrintToString(obj); + } + } +} \ No newline at end of file diff --git a/ObjectPrinting/ObjectPrinting.csproj b/ObjectPrinting/ObjectPrinting.csproj index c5db392f..9a86d3d3 100644 --- a/ObjectPrinting/ObjectPrinting.csproj +++ b/ObjectPrinting/ObjectPrinting.csproj @@ -5,8 +5,5 @@ - - - diff --git a/ObjectPrinting/PrintingConfig.cs b/ObjectPrinting/PrintingConfig.cs index a9e08211..2cd0e754 100644 --- a/ObjectPrinting/PrintingConfig.cs +++ b/ObjectPrinting/PrintingConfig.cs @@ -1,41 +1,155 @@ -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 { public class PrintingConfig { + private readonly HashSet typesToExclude = []; + private readonly HashSet propertiesToExclude = []; + private readonly Dictionary> typePrinters = []; + private readonly Dictionary> propertyPrinters = []; + private readonly HashSet visitedObjects = []; + + public PropertyPrintingConfig Printing() + { + return new PropertyPrintingConfig(this); + } + + public PropertyPrintingConfig Printing(Expression> memberSelector) + { + return new PropertyPrintingConfig(this, memberSelector.Name); + } + + public PrintingConfig Excluding(Expression> memberSelector) + { + if (memberSelector.Body is not MemberExpression memberExpression) + throw new ArgumentException("Wrong Expression"); + propertiesToExclude.Add(memberExpression.Member.Name); + return this; + } + + public PrintingConfig Excluding() + { + typesToExclude.Add(typeof(TPropType)); + 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; + return "null" ; - 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 type = obj.GetType(); - var identation = new string('\t', nestingLevel + 1); - var sb = new StringBuilder(); + if (visitedObjects.Contains(obj, ReferenceEqualityComparer.Instance)) + return "Loop found"; + + if (typesToExclude.Contains(type)) + return string.Empty; + + visitedObjects.Add(obj); + + if (typePrinters.TryGetValue(type, out var printer)) + return printer(obj); + + if (FinalTypes.Set.Contains(type)) + return obj.ToString(); + + if (obj is not ICollection) return PrintObj(obj, nestingLevel); + var collection = (IEnumerable) obj; + return PrintCollection(collection, nestingLevel); + } + + private string PrintObj( object obj, int nestingLevel) + { var type = obj.GetType(); + var indentation = new string('\t', nestingLevel + 1); + var sb = new StringBuilder(); sb.AppendLine(type.Name); - foreach (var propertyInfo in type.GetProperties()) + + foreach (var memberInfo in type + .GetProperties() + .Cast() + .Concat(type.GetFields(BindingFlags.Instance | BindingFlags.Public))) { - sb.Append(identation + propertyInfo.Name + " = " + - PrintToString(propertyInfo.GetValue(obj), - nestingLevel + 1)); + + var name = memberInfo.Name; + var value = memberInfo.GetValue(obj); + if (value == null) + { + sb.Append(indentation + name + " = null\n"); + continue; + } + + var propertyType = value.GetType(); + + if (propertyPrinters.TryGetValue(name, out var propertyPrinter)) + { + sb.AppendLine(propertyPrinter(value)); + continue; + } + + if (typesToExclude.Contains(propertyType) || propertiesToExclude.Contains(name)) + continue; + + sb.Append(indentation + name + " = "); + sb.AppendLine(PrintToString(value, nestingLevel + 1)); + } + return sb.ToString(); + } + + private string PrintCollection(IEnumerable collection, int nestingLevel) + { + if (collection is IDictionary dictionary) + return PrintDictionary( dictionary, nestingLevel); + + var indentation = new string('\t', nestingLevel + 1); + var sb = new StringBuilder(); + + foreach (var element in collection) + { + sb.Append("\n" + indentation); + sb.Append(PrintToString(element, nestingLevel + 1)); } return sb.ToString(); } + + private string PrintDictionary(IDictionary collection, int nestingLevel) + { + var indentation = new string('\t', nestingLevel + 1); + var sb = new StringBuilder(); + + foreach (var key in collection.Keys) + { + sb.Append("\n" + indentation); + sb.Append("key = "); + sb.Append(PrintToString(key, nestingLevel + 1)); + sb.Append("\n" + indentation); + sb.Append("value = "); + sb.Append(PrintToString(collection[key], nestingLevel + 1)); + } + return sb.ToString(); + } + + public void AddTypePrinter(Func print) + { + typePrinters[typeof(TPropType)] = obj => print((TPropType)obj); + } + + internal void AddPropertyPrinter(string propName, Func print) + { + propertyPrinters[propName] = print; + } } } \ No newline at end of file diff --git a/ObjectPrinting/PropertyPrintingConfig.cs b/ObjectPrinting/PropertyPrintingConfig.cs new file mode 100644 index 00000000..1281f118 --- /dev/null +++ b/ObjectPrinting/PropertyPrintingConfig.cs @@ -0,0 +1,32 @@ +using System; +using System.Globalization; + +namespace ObjectPrinting +{ + public class PropertyPrintingConfig + : IPropertyPrintingConfig + { + private readonly PrintingConfig printingConfig; + private readonly string propName; + + public PropertyPrintingConfig(PrintingConfig printingConfig, string propName = null) + { + this.printingConfig = printingConfig; + this.propName = propName; + } + + public PrintingConfig Using(Func print) + { + if(propName == null) + this.printingConfig.AddTypePrinter(print); + else + printingConfig.AddPropertyPrinter(propName, x => print((TPropType)x)); + return printingConfig; + } + } + + public interface IPropertyPrintingConfig + { + public PrintingConfig Using(Func print); + } +} \ No newline at end of file diff --git a/ObjectPrinting/PropertyPrintingConfigExtensions.cs b/ObjectPrinting/PropertyPrintingConfigExtensions.cs new file mode 100644 index 00000000..e00c191e --- /dev/null +++ b/ObjectPrinting/PropertyPrintingConfigExtensions.cs @@ -0,0 +1,25 @@ +using System; +using System.Globalization; + +namespace ObjectPrinting +{ + public static class PropertyPrintingConfigExtensions + { + public static PrintingConfig SetCulture + (this IPropertyPrintingConfig config, + CultureInfo culture) + where TPropType : IFormattable + { + return config.Using(x => x.ToString(null, culture)); + } + + public static PrintingConfig TrimmedToLength(this PropertyPrintingConfig propConfig, int maxLen) + { + return propConfig.Using(x => + (x.Length > maxLen) + ? x[..maxLen] + : x); + } + } +} \ No newline at end of file diff --git a/ObjectPrinting/Solved/PrintingConfig.cs b/ObjectPrinting/Solved/PrintingConfig.cs index 0ec5aeb2..1cdc571a 100644 --- a/ObjectPrinting/Solved/PrintingConfig.cs +++ b/ObjectPrinting/Solved/PrintingConfig.cs @@ -32,7 +32,7 @@ public string PrintToString(TOwner obj) return PrintToString(obj, 0); } - private string PrintToString(object obj, int nestingLevel) + private static string PrintToString(object obj, int nestingLevel) { //TODO apply configurations if (obj == null) 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/Samples/FluentMapper.Tests/FluentMapping.Tests.csproj b/Samples/FluentMapper.Tests/FluentMapping.Tests.csproj index 3828c566..a580ad54 100644 --- a/Samples/FluentMapper.Tests/FluentMapping.Tests.csproj +++ b/Samples/FluentMapper.Tests/FluentMapping.Tests.csproj @@ -9,6 +9,7 @@ + diff --git a/Samples/FluentMapper/FluentMapping.csproj b/Samples/FluentMapper/FluentMapping.csproj index fa71b7ae..a4f2550a 100644 --- a/Samples/FluentMapper/FluentMapping.csproj +++ b/Samples/FluentMapper/FluentMapping.csproj @@ -6,4 +6,8 @@ enable + + + + diff --git a/Samples/Spectacle/Spectacle.csproj b/Samples/Spectacle/Spectacle.csproj index fa71b7ae..a4f2550a 100644 --- a/Samples/Spectacle/Spectacle.csproj +++ b/Samples/Spectacle/Spectacle.csproj @@ -6,4 +6,8 @@ enable + + + + diff --git a/fluent-api.sln b/fluent-api.sln index 69c8db9e..b4a001bb 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.11.35327.3 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}") = "ObjectPrinting.Tests", "ObjectPrinting.Tests\ObjectPrinting.Tests.csproj", "{13FB7EA2-3C1E-442A-A43A-8246005FD7BE}" 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 + {13FB7EA2-3C1E-442A-A43A-8246005FD7BE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {13FB7EA2-3C1E-442A-A43A-8246005FD7BE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {13FB7EA2-3C1E-442A-A43A-8246005FD7BE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {13FB7EA2-3C1E-442A-A43A-8246005FD7BE}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/fluent-api.sln.DotSettings b/fluent-api.sln.DotSettings index 135b83ec..229f449d 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" 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" Prefix="" Suffix="" Style="AaBb_AaBb" /></Policy> + True True True Imported 10.10.2016