From d506d406087b2ec8daec555c56e0ffd015bfc9f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Sun, 5 Apr 2020 22:30:36 +0300 Subject: [PATCH] Allow to ignore some properties on mapping extensible objects. --- .../AbpAutoMapperExtensibleDtoExtensions.cs | 8 +- .../ObjectExtending/ExtendedObjectMapper.cs | 237 ++++++++++++++++++ ...xtraPropertiesObjectExtendingExtensions.cs | 199 +-------------- ...AutoMapperExtensibleDtoExtensions_Tests.cs | 6 +- .../ObjectMapperExtensions_Tests.cs | 8 +- .../AutoMapper/SampleClasses/MyMapProfile.cs | 2 +- .../AbpObjectExtendingTestModule.cs | 4 +- ...opertiesObjectExtendingExtensions_Tests.cs | 27 +- 8 files changed, 291 insertions(+), 200 deletions(-) create mode 100644 framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ExtendedObjectMapper.cs diff --git a/framework/src/Volo.Abp.AutoMapper/AutoMapper/AbpAutoMapperExtensibleDtoExtensions.cs b/framework/src/Volo.Abp.AutoMapper/AutoMapper/AbpAutoMapperExtensibleDtoExtensions.cs index 664e35e9b0..40be84cb6f 100644 --- a/framework/src/Volo.Abp.AutoMapper/AutoMapper/AbpAutoMapperExtensibleDtoExtensions.cs +++ b/framework/src/Volo.Abp.AutoMapper/AutoMapper/AbpAutoMapperExtensibleDtoExtensions.cs @@ -8,7 +8,8 @@ namespace AutoMapper { public static IMappingExpression MapExtraProperties( this IMappingExpression mappingExpression, - MappingPropertyDefinitionChecks? definitionChecks = null) + MappingPropertyDefinitionChecks? definitionChecks = null, + string[] ignoredProperties = null) where TDestination : IHasExtraProperties where TSource : IHasExtraProperties { @@ -22,11 +23,12 @@ namespace AutoMapper ? new Dictionary() : new Dictionary(extraProps); - HasExtraPropertiesObjectExtendingExtensions + ExtensibleObjectMapper .MapExtraPropertiesTo( source.ExtraProperties, result, - definitionChecks + definitionChecks, + ignoredProperties ); return result; diff --git a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ExtendedObjectMapper.cs b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ExtendedObjectMapper.cs new file mode 100644 index 0000000000..f2b7aeecdb --- /dev/null +++ b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ExtendedObjectMapper.cs @@ -0,0 +1,237 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using JetBrains.Annotations; +using Volo.Abp.Data; + +namespace Volo.Abp.ObjectExtending +{ + public static class ExtensibleObjectMapper + { + /// + /// Copies extra properties from the object + /// to the object. + /// + /// Checks property definitions (over the ) + /// based on the preference. + /// + /// Source class type + /// Destination class type + /// The source object + /// The destination object + /// + /// Controls which properties to map. + /// + /// Used to ignore some properties + public static void MapExtraPropertiesTo( + [NotNull] TSource source, + [NotNull] TDestination destination, + MappingPropertyDefinitionChecks? definitionChecks = null, + string[] ignoredProperties = null) + where TSource : IHasExtraProperties + where TDestination : IHasExtraProperties + { + Check.NotNull(source, nameof(source)); + Check.NotNull(destination, nameof(destination)); + + ExtensibleObjectMapper.MapExtraPropertiesTo( + typeof(TSource), + typeof(TDestination), + source.ExtraProperties, + destination.ExtraProperties, + definitionChecks, + ignoredProperties + ); + } + + /// + /// Copies extra properties from the object + /// to the object. + /// + /// Checks property definitions (over the ) + /// based on the preference. + /// + /// Source class type (for definition check) + /// Destination class type (for definition check) + /// The source dictionary object + /// The destination dictionary object + /// + /// Controls which properties to map. + /// + /// Used to ignore some properties + public static void MapExtraPropertiesTo( + [NotNull] Dictionary sourceDictionary, + [NotNull] Dictionary destinationDictionary, + MappingPropertyDefinitionChecks? definitionChecks = null, + string[] ignoredProperties = null) + where TSource : IHasExtraProperties + where TDestination : IHasExtraProperties + { + MapExtraPropertiesTo( + typeof(TSource), + typeof(TDestination), + sourceDictionary, + destinationDictionary, + definitionChecks, + ignoredProperties + ); + } + + /// + /// Copies extra properties from the object + /// to the object. + /// + /// Checks property definitions (over the ) + /// based on the preference. + /// + /// Source type (for definition check) + /// Destination class type (for definition check) + /// The source dictionary object + /// The destination dictionary object + /// + /// Controls which properties to map. + /// + /// Used to ignore some properties + public static void MapExtraPropertiesTo( + [NotNull] Type sourceType, + [NotNull] Type destinationType, + [NotNull] Dictionary sourceDictionary, + [NotNull] Dictionary destinationDictionary, + MappingPropertyDefinitionChecks? definitionChecks = null, + string[] ignoredProperties = null) + { + Check.AssignableTo(sourceType, nameof(sourceType)); + Check.AssignableTo(destinationType, nameof(destinationType)); + Check.NotNull(sourceDictionary, nameof(sourceDictionary)); + Check.NotNull(destinationDictionary, nameof(destinationDictionary)); + + var sourceObjectExtension = ObjectExtensionManager.Instance.GetOrNull(sourceType); + var destinationObjectExtension = ObjectExtensionManager.Instance.GetOrNull(destinationType); + + foreach (var keyValue in sourceDictionary) + { + if (CanMapProperty( + keyValue.Key, + sourceObjectExtension, + destinationObjectExtension, + definitionChecks, + ignoredProperties)) + { + destinationDictionary[keyValue.Key] = keyValue.Value; + } + } + } + + //TODO: Move these methods to a class like ObjectExtensionHelper + + public static bool CanMapProperty( + [NotNull] string propertyName, + MappingPropertyDefinitionChecks? definitionChecks = null, + string[] ignoredProperties = null) + { + return CanMapProperty( + typeof(TSource), + typeof(TDestination), + propertyName, + definitionChecks, + ignoredProperties + ); + } + + public static bool CanMapProperty( + [NotNull] Type sourceType, + [NotNull] Type destinationType, + [NotNull] string propertyName, + MappingPropertyDefinitionChecks? definitionChecks = null, + string[] ignoredProperties = null) + { + Check.AssignableTo(sourceType, nameof(sourceType)); + Check.AssignableTo(destinationType, nameof(destinationType)); + Check.NotNull(propertyName, nameof(propertyName)); + + var sourceObjectExtension = ObjectExtensionManager.Instance.GetOrNull(sourceType); + var destinationObjectExtension = ObjectExtensionManager.Instance.GetOrNull(destinationType); + + return CanMapProperty( + propertyName, + sourceObjectExtension, + destinationObjectExtension, + definitionChecks, + ignoredProperties); + } + + private static bool CanMapProperty( + [NotNull] string propertyName, + [CanBeNull] ObjectExtensionInfo sourceObjectExtension, + [CanBeNull] ObjectExtensionInfo destinationObjectExtension, + MappingPropertyDefinitionChecks? definitionChecks = null, + string[] ignoredProperties = null) + { + Check.NotNull(propertyName, nameof(propertyName)); + + if (ignoredProperties != null && + ignoredProperties.Contains(propertyName)) + { + return false; + } + + if (definitionChecks != null) + { + if (definitionChecks.Value.HasFlag(MappingPropertyDefinitionChecks.Source)) + { + if (sourceObjectExtension == null) + { + return false; + } + + if (!sourceObjectExtension.HasProperty(propertyName)) + { + return false; + } + } + + if (definitionChecks.Value.HasFlag(MappingPropertyDefinitionChecks.Destination)) + { + if (destinationObjectExtension == null) + { + return false; + } + + if (!destinationObjectExtension.HasProperty(propertyName)) + { + return false; + } + } + + return true; + } + else + { + var sourcePropertyDefinition = sourceObjectExtension?.GetPropertyOrNull(propertyName); + var destinationPropertyDefinition = destinationObjectExtension?.GetPropertyOrNull(propertyName); + + if (sourcePropertyDefinition != null) + { + if (destinationPropertyDefinition != null) + { + return true; + } + + if (sourcePropertyDefinition.CheckPairDefinitionOnMapping == false) + { + return true; + } + } + else if (destinationPropertyDefinition != null) + { + if (destinationPropertyDefinition.CheckPairDefinitionOnMapping == false) + { + return true; + } + } + + return false; + } + } + } +} diff --git a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/HasExtraPropertiesObjectExtendingExtensions.cs b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/HasExtraPropertiesObjectExtendingExtensions.cs index 6b687fcf81..051b1fd0ad 100644 --- a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/HasExtraPropertiesObjectExtendingExtensions.cs +++ b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/HasExtraPropertiesObjectExtendingExtensions.cs @@ -1,6 +1,4 @@ -using System; -using System.Collections.Generic; -using JetBrains.Annotations; +using JetBrains.Annotations; using Volo.Abp.Data; namespace Volo.Abp.ObjectExtending @@ -10,7 +8,7 @@ namespace Volo.Abp.ObjectExtending /// /// Copies extra properties from the object /// to the object. - /// + /// /// Checks property definitions (over the ) /// based on the preference. /// @@ -19,198 +17,23 @@ namespace Volo.Abp.ObjectExtending /// The source object /// The destination object /// - /// Controls which properties to map. + /// Controls which properties to map. /// + /// Used to ignore some properties public static void MapExtraPropertiesTo( [NotNull] this TSource source, [NotNull] TDestination destination, - MappingPropertyDefinitionChecks? definitionChecks = null) - where TSource : IHasExtraProperties - where TDestination : IHasExtraProperties - { - Check.NotNull(source, nameof(source)); - Check.NotNull(destination, nameof(destination)); - - MapExtraPropertiesTo( - typeof(TSource), - typeof(TDestination), - source.ExtraProperties, - destination.ExtraProperties, - definitionChecks - ); - } - - /// - /// Copies extra properties from the object - /// to the object. - /// - /// Checks property definitions (over the ) - /// based on the preference. - /// - /// Source class type (for definition check) - /// Destination class type (for definition check) - /// The source dictionary object - /// The destination dictionary object - /// - /// Controls which properties to map. - /// - public static void MapExtraPropertiesTo( - [NotNull] Dictionary sourceDictionary, - [NotNull] Dictionary destinationDictionary, - MappingPropertyDefinitionChecks? definitionChecks = null) + MappingPropertyDefinitionChecks? definitionChecks = null, + string[] ignoredProperties = null) where TSource : IHasExtraProperties where TDestination : IHasExtraProperties { - MapExtraPropertiesTo( - typeof(TSource), - typeof(TDestination), - sourceDictionary, - destinationDictionary, - definitionChecks + ExtensibleObjectMapper.MapExtraPropertiesTo( + source, + destination, + definitionChecks, + ignoredProperties ); } - - /// - /// Copies extra properties from the object - /// to the object. - /// - /// Checks property definitions (over the ) - /// based on the preference. - /// - /// Source type (for definition check) - /// Destination class type (for definition check) - /// The source dictionary object - /// The destination dictionary object - /// - /// Controls which properties to map. - /// - public static void MapExtraPropertiesTo( - [NotNull] Type sourceType, - [NotNull] Type destinationType, - [NotNull] Dictionary sourceDictionary, - [NotNull] Dictionary destinationDictionary, - MappingPropertyDefinitionChecks? definitionChecks = null) - { - Check.AssignableTo(sourceType, nameof(sourceType)); - Check.AssignableTo(destinationType, nameof(destinationType)); - Check.NotNull(sourceDictionary, nameof(sourceDictionary)); - Check.NotNull(destinationDictionary, nameof(destinationDictionary)); - - var sourceObjectExtension = ObjectExtensionManager.Instance.GetOrNull(sourceType); - var destinationObjectExtension = ObjectExtensionManager.Instance.GetOrNull(destinationType); - - foreach (var keyValue in sourceDictionary) - { - if (CanMapProperty( - keyValue.Key, - sourceObjectExtension, - destinationObjectExtension, - definitionChecks)) - { - destinationDictionary[keyValue.Key] = keyValue.Value; - } - } - } - - //TODO: Move these methods to a class like ObjectExtensionHelper - - public static bool CanMapProperty( - [NotNull] string propertyName, - MappingPropertyDefinitionChecks? definitionChecks = null) - { - return CanMapProperty( - typeof(TSource), - typeof(TDestination), - propertyName, - definitionChecks - ); - } - - public static bool CanMapProperty( - [NotNull] Type sourceType, - [NotNull] Type destinationType, - [NotNull] string propertyName, - MappingPropertyDefinitionChecks? definitionChecks = null) - { - Check.AssignableTo(sourceType, nameof(sourceType)); - Check.AssignableTo(destinationType, nameof(destinationType)); - Check.NotNull(propertyName, nameof(propertyName)); - - var sourceObjectExtension = ObjectExtensionManager.Instance.GetOrNull(sourceType); - var destinationObjectExtension = ObjectExtensionManager.Instance.GetOrNull(destinationType); - - return CanMapProperty( - propertyName, - sourceObjectExtension, - destinationObjectExtension, - definitionChecks); - } - - private static bool CanMapProperty( - [NotNull] string propertyName, - [CanBeNull] ObjectExtensionInfo sourceObjectExtension, - [CanBeNull] ObjectExtensionInfo destinationObjectExtension, - MappingPropertyDefinitionChecks? definitionChecks = null) - { - Check.NotNull(propertyName, nameof(propertyName)); - - if (definitionChecks != null) - { - if (definitionChecks.Value.HasFlag(MappingPropertyDefinitionChecks.Source)) - { - if (sourceObjectExtension == null) - { - return false; - } - - if (!sourceObjectExtension.HasProperty(propertyName)) - { - return false; - } - } - - if (definitionChecks.Value.HasFlag(MappingPropertyDefinitionChecks.Destination)) - { - if (destinationObjectExtension == null) - { - return false; - } - - if (!destinationObjectExtension.HasProperty(propertyName)) - { - return false; - } - } - - return true; - } - else - { - var sourcePropertyDefinition = sourceObjectExtension?.GetPropertyOrNull(propertyName); - var destinationPropertyDefinition = destinationObjectExtension?.GetPropertyOrNull(propertyName); - - if (sourcePropertyDefinition != null) - { - if (destinationPropertyDefinition != null) - { - return true; - } - - if (sourcePropertyDefinition.CheckPairDefinitionOnMapping == false) - { - return true; - } - } - else if (destinationPropertyDefinition != null) - { - if (destinationPropertyDefinition.CheckPairDefinitionOnMapping == false) - { - return true; - } - } - - return false; - } - } } } \ No newline at end of file diff --git a/framework/test/Volo.Abp.AutoMapper.Tests/AutoMapper/AbpAutoMapperExtensibleDtoExtensions_Tests.cs b/framework/test/Volo.Abp.AutoMapper.Tests/AutoMapper/AbpAutoMapperExtensibleDtoExtensions_Tests.cs index a55e7d32e3..d0ee7db52d 100644 --- a/framework/test/Volo.Abp.AutoMapper.Tests/AutoMapper/AbpAutoMapperExtensibleDtoExtensions_Tests.cs +++ b/framework/test/Volo.Abp.AutoMapper.Tests/AutoMapper/AbpAutoMapperExtensibleDtoExtensions_Tests.cs @@ -24,7 +24,8 @@ namespace AutoMapper .SetProperty("Name", "John") .SetProperty("Age", 42) .SetProperty("ChildCount", 2) - .SetProperty("Sex", "male"); + .SetProperty("Sex", "male") + .SetProperty("CityName", "Adana"); var personDto = new ExtensibleTestPersonDto() .SetProperty("ExistingDtoProperty", "existing-value"); @@ -32,10 +33,11 @@ namespace AutoMapper _objectMapper.Map(person, personDto); personDto.GetProperty("Name").ShouldBe("John"); //Defined in both classes + personDto.GetProperty("ExistingDtoProperty").ShouldBe("existing-value"); //Should not clear existing values personDto.HasProperty("Age").ShouldBeFalse(); //Not defined on the destination personDto.HasProperty("ChildCount").ShouldBeFalse(); //Not defined in the source personDto.HasProperty("Sex").ShouldBeFalse(); //Not defined in both classes - personDto.GetProperty("ExistingDtoProperty").ShouldBe("existing-value"); //Should not clear existing values + personDto.HasProperty("CityName").ShouldBeFalse(); //Ignored } } } diff --git a/framework/test/Volo.Abp.AutoMapper.Tests/Volo/Abp/AutoMapper/ObjectMapperExtensions_Tests.cs b/framework/test/Volo.Abp.AutoMapper.Tests/Volo/Abp/AutoMapper/ObjectMapperExtensions_Tests.cs index 737731fd22..699159dc7d 100644 --- a/framework/test/Volo.Abp.AutoMapper.Tests/Volo/Abp/AutoMapper/ObjectMapperExtensions_Tests.cs +++ b/framework/test/Volo.Abp.AutoMapper.Tests/Volo/Abp/AutoMapper/ObjectMapperExtensions_Tests.cs @@ -20,7 +20,13 @@ namespace Volo.Abp.AutoMapper [Fact] public void Should_Map_Objects_With_AutoMap_Attributes() { - var dto = _objectMapper.Map(typeof(MyEntity), typeof(MyEntityDto), new MyEntity { Number = 42 }); + var dto = _objectMapper.Map( + new MyEntity + { + Number = 42 + } + ); + dto.As().Number.ShouldBe(42); } } diff --git a/framework/test/Volo.Abp.AutoMapper.Tests/Volo/Abp/AutoMapper/SampleClasses/MyMapProfile.cs b/framework/test/Volo.Abp.AutoMapper.Tests/Volo/Abp/AutoMapper/SampleClasses/MyMapProfile.cs index 7fb8dbd2fa..6c69d53e5f 100644 --- a/framework/test/Volo.Abp.AutoMapper.Tests/Volo/Abp/AutoMapper/SampleClasses/MyMapProfile.cs +++ b/framework/test/Volo.Abp.AutoMapper.Tests/Volo/Abp/AutoMapper/SampleClasses/MyMapProfile.cs @@ -10,7 +10,7 @@ namespace Volo.Abp.AutoMapper.SampleClasses CreateMap().ReverseMap(); CreateMap() - .MapExtraProperties(); + .MapExtraProperties(ignoredProperties: new[] { "CityName" }); } } } diff --git a/framework/test/Volo.Abp.ObjectExtending.Tests/Volo/Abp/ObjectExtending/AbpObjectExtendingTestModule.cs b/framework/test/Volo.Abp.ObjectExtending.Tests/Volo/Abp/ObjectExtending/AbpObjectExtendingTestModule.cs index 470bb547e5..3eff9846f7 100644 --- a/framework/test/Volo.Abp.ObjectExtending.Tests/Volo/Abp/ObjectExtending/AbpObjectExtendingTestModule.cs +++ b/framework/test/Volo.Abp.ObjectExtending.Tests/Volo/Abp/ObjectExtending/AbpObjectExtendingTestModule.cs @@ -20,8 +20,10 @@ namespace Volo.Abp.ObjectExtending .AddOrUpdateProperty("Name") .AddOrUpdateProperty("Age") .AddOrUpdateProperty("NoPairCheck", options => options.CheckPairDefinitionOnMapping = false) + .AddOrUpdateProperty("CityName") .AddOrUpdateProperty("Name") - .AddOrUpdateProperty("ChildCount"); + .AddOrUpdateProperty("ChildCount") + .AddOrUpdateProperty("CityName"); }); } } diff --git a/framework/test/Volo.Abp.ObjectExtending.Tests/Volo/Abp/ObjectExtending/HasExtraPropertiesObjectExtendingExtensions_Tests.cs b/framework/test/Volo.Abp.ObjectExtending.Tests/Volo/Abp/ObjectExtending/HasExtraPropertiesObjectExtendingExtensions_Tests.cs index 7ba213b81c..e871aeb056 100644 --- a/framework/test/Volo.Abp.ObjectExtending.Tests/Volo/Abp/ObjectExtending/HasExtraPropertiesObjectExtendingExtensions_Tests.cs +++ b/framework/test/Volo.Abp.ObjectExtending.Tests/Volo/Abp/ObjectExtending/HasExtraPropertiesObjectExtendingExtensions_Tests.cs @@ -17,23 +17,39 @@ namespace Volo.Abp.ObjectExtending .SetProperty("Age", 42) .SetProperty("ChildCount", 2) .SetProperty("Sex", "male") - .SetProperty("NoPairCheck", "test-value"); + .SetProperty("NoPairCheck", "test-value") + .SetProperty("CityName", "Adana"); _personDto = new ExtensibleTestPersonDto() .SetProperty("ExistingDtoProperty", "existing-value"); } - + [Fact] public void MapExtraPropertiesTo_Should_Only_Map_Defined_Properties_By_Default() { _person.MapExtraPropertiesTo(_personDto); _personDto.GetProperty("Name").ShouldBe("John"); //Defined in both classes + _personDto.GetProperty("CityName").ShouldBe("Adana"); //Defined in both classes + _personDto.GetProperty("NoPairCheck").ShouldBe("test-value"); //CheckPairDefinitionOnMapping = false + _personDto.GetProperty("ExistingDtoProperty").ShouldBe("existing-value"); //Should not clear existing values _personDto.HasProperty("Age").ShouldBeFalse(); //Not defined on the destination _personDto.HasProperty("ChildCount").ShouldBeFalse(); //Not defined in the source _personDto.HasProperty("Sex").ShouldBeFalse(); //Not defined in both classes + } + + [Fact] + public void MapExtraPropertiesTo_Should_Ignore_Desired_Properties() + { + _person.MapExtraPropertiesTo(_personDto, ignoredProperties: new[] { "CityName" }); + + _personDto.GetProperty("Name").ShouldBe("John"); //Defined in both classes _personDto.GetProperty("NoPairCheck").ShouldBe("test-value"); //CheckPairDefinitionOnMapping = false _personDto.GetProperty("ExistingDtoProperty").ShouldBe("existing-value"); //Should not clear existing values + _personDto.HasProperty("CityName").ShouldBeFalse(); //Ignored! + _personDto.HasProperty("Age").ShouldBeFalse(); //Not defined on the destination + _personDto.HasProperty("ChildCount").ShouldBeFalse(); //Not defined in the source + _personDto.HasProperty("Sex").ShouldBeFalse(); //Not defined in both classes } [Fact] @@ -42,10 +58,11 @@ namespace Volo.Abp.ObjectExtending _person.MapExtraPropertiesTo(_personDto, MappingPropertyDefinitionChecks.Source); _personDto.GetProperty("Name").ShouldBe("John"); //Defined in both classes + _personDto.GetProperty("CityName").ShouldBe("Adana"); //Defined in both classes _personDto.GetProperty("Age").ShouldBe(42); //Defined in source + _personDto.GetProperty("ExistingDtoProperty").ShouldBe("existing-value"); //Should not clear existing values _personDto.HasProperty("ChildCount").ShouldBeFalse(); //Not defined in the source _personDto.HasProperty("Sex").ShouldBeFalse(); //Not defined in both classes - _personDto.GetProperty("ExistingDtoProperty").ShouldBe("existing-value"); //Should not clear existing values } [Fact] @@ -54,10 +71,11 @@ namespace Volo.Abp.ObjectExtending _person.MapExtraPropertiesTo(_personDto, MappingPropertyDefinitionChecks.Destination); _personDto.GetProperty("Name").ShouldBe("John"); //Defined in both classes + _personDto.GetProperty("CityName").ShouldBe("Adana"); //Defined in both classes _personDto.GetProperty("ChildCount").ShouldBe(2); //Defined in destination + _personDto.GetProperty("ExistingDtoProperty").ShouldBe("existing-value"); //Should not clear existing values _personDto.HasProperty("Age").ShouldBeFalse(); //Not defined in destination _personDto.HasProperty("Sex").ShouldBeFalse(); //Not defined in both classes - _personDto.GetProperty("ExistingDtoProperty").ShouldBe("existing-value"); //Should not clear existing values } [Fact] @@ -66,6 +84,7 @@ namespace Volo.Abp.ObjectExtending _person.MapExtraPropertiesTo(_personDto, MappingPropertyDefinitionChecks.None); _personDto.GetProperty("Name").ShouldBe("John"); + _personDto.GetProperty("CityName").ShouldBe("Adana"); _personDto.GetProperty("Age").ShouldBe(42); _personDto.GetProperty("ChildCount").ShouldBe(2); _personDto.GetProperty("Sex").ShouldBe("male");