From d2985a026b56084e430063eccd8801e703971434 Mon Sep 17 00:00:00 2001 From: Tom Scheler Date: Wed, 26 Feb 2020 21:20:15 +0100 Subject: [PATCH 1/2] Fixed attribute-based reverse mapping with SourceMemberAttribute #3129 #3329 --- .../MapperConfigurationExpression.cs | 6 +- src/UnitTests/AttributeBasedMaps.cs | 76 +++++++++++++++++++ 2 files changed, 80 insertions(+), 2 deletions(-) diff --git a/src/AutoMapper/Configuration/MapperConfigurationExpression.cs b/src/AutoMapper/Configuration/MapperConfigurationExpression.cs index 50002f7b32..6a57090815 100644 --- a/src/AutoMapper/Configuration/MapperConfigurationExpression.cs +++ b/src/AutoMapper/Configuration/MapperConfigurationExpression.cs @@ -87,11 +87,11 @@ private void AddMapsCore(IEnumerable assembliesToScan) { AddProfile(type.AsType()); } + foreach (var autoMapAttribute in type.GetCustomAttributes()) { var mappingExpression = (MappingExpression) autoMapAttributeProfile.CreateMap(autoMapAttribute.SourceType, type); - autoMapAttribute.ApplyConfiguration(mappingExpression); - + foreach (var memberInfo in type.GetMembers(BindingFlags.Public | BindingFlags.Instance)) { foreach (var memberConfigurationProvider in memberInfo.GetCustomAttributes().OfType()) @@ -99,6 +99,8 @@ private void AddMapsCore(IEnumerable assembliesToScan) mappingExpression.ForMember(memberInfo, cfg => memberConfigurationProvider.ApplyConfiguration(cfg)); } } + + autoMapAttribute.ApplyConfiguration(mappingExpression); } } diff --git a/src/UnitTests/AttributeBasedMaps.cs b/src/UnitTests/AttributeBasedMaps.cs index 39e651f50c..ff25e055ac 100644 --- a/src/UnitTests/AttributeBasedMaps.cs +++ b/src/UnitTests/AttributeBasedMaps.cs @@ -77,6 +77,82 @@ public void Should_validate_successfully() } } + public class When_specifying_map_and_reverse_map_with_attribute_and_sourcemember_attribute : NonValidatingSpecBase + { + public class Source + { + public int Value { get; set; } + } + + [AutoMap(typeof(Source), ReverseMap = true)] + public class Destination + { + [SourceMember("Value")] + public int Value2 { get; set; } + } + + protected override MapperConfiguration Configuration { get; } = new MapperConfiguration(cfg => + { + cfg.AddMaps(typeof(When_specifying_map_and_reverse_map_with_attribute_and_sourcemember_attribute)); + }); + + [Fact] + public void Should_reverse_map() + { + var destination = new Destination { Value2 = 5 }; + var source = Mapper.Map(destination); + source.Value.ShouldBe(5); + } + + [Fact] + public void Should_validate_successfully() + { + typeof(AutoMapperConfigurationException).ShouldNotBeThrownBy(() => Configuration.AssertConfigurationIsValid(Configuration.FindTypeMapFor())); + typeof(AutoMapperConfigurationException).ShouldNotBeThrownBy(() => Configuration.AssertConfigurationIsValid(Configuration.FindTypeMapFor())); + } + } + + public class When_specifying_open_generic_map_and_reverse_map_with_attribute_and_sourcemember_attribute : NonValidatingSpecBase + { + public class Source + { + public T Value { get; set; } + + public string StringValue { get; set; } + } + + [AutoMap(typeof(Source<>), ReverseMap = true)] + public class Destination + { + [SourceMember("Value")] + public int Value2 { get; set; } + + [SourceMember("StringValue")] + public string StringValue2 { get; set; } + } + + protected override MapperConfiguration Configuration { get; } = new MapperConfiguration(cfg => + { + cfg.AddMaps(typeof(When_specifying_open_generic_map_and_reverse_map_with_attribute_and_sourcemember_attribute)); + }); + + [Fact] + public void Should_reverse_map() + { + Destination destination = new Destination { Value2 = 5, StringValue2 = "Joe" }; + Source source = Mapper.Map>(destination); + source.Value.ShouldBe(5); + source.StringValue.ShouldBe("Joe"); + } + + [Fact] + public void Should_validate_successfully() + { + typeof(AutoMapperConfigurationException).ShouldNotBeThrownBy(() => Configuration.AssertConfigurationIsValid(Configuration.FindTypeMapFor(typeof(Source<>), typeof(Destination<>)))); + typeof(AutoMapperConfigurationException).ShouldNotBeThrownBy(() => Configuration.AssertConfigurationIsValid(Configuration.FindTypeMapFor(typeof(Destination<>), typeof(Source<>)))); + } + } + public class When_duplicating_map_configuration_with_code_and_attribute : NonValidatingSpecBase { public class Source From 1ea048a13e58375d34db809153ca23d40d3fc0ff Mon Sep 17 00:00:00 2001 From: Tom Scheler Date: Thu, 27 Feb 2020 12:13:49 +0100 Subject: [PATCH 2/2] renaming --- src/UnitTests/AttributeBasedMaps.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/UnitTests/AttributeBasedMaps.cs b/src/UnitTests/AttributeBasedMaps.cs index ff25e055ac..3f0a0968cd 100644 --- a/src/UnitTests/AttributeBasedMaps.cs +++ b/src/UnitTests/AttributeBasedMaps.cs @@ -77,7 +77,7 @@ public void Should_validate_successfully() } } - public class When_specifying_map_and_reverse_map_with_attribute_and_sourcemember_attribute : NonValidatingSpecBase + public class When_specifying_reverse_map_with_sourcemember_attribute : NonValidatingSpecBase { public class Source { @@ -93,7 +93,7 @@ public class Destination protected override MapperConfiguration Configuration { get; } = new MapperConfiguration(cfg => { - cfg.AddMaps(typeof(When_specifying_map_and_reverse_map_with_attribute_and_sourcemember_attribute)); + cfg.AddMaps(typeof(When_specifying_reverse_map_with_sourcemember_attribute)); }); [Fact] @@ -112,7 +112,7 @@ public void Should_validate_successfully() } } - public class When_specifying_open_generic_map_and_reverse_map_with_attribute_and_sourcemember_attribute : NonValidatingSpecBase + public class When_specifying_generic_reverse_map_with_sourcemember_attribute : NonValidatingSpecBase { public class Source { @@ -133,7 +133,7 @@ public class Destination protected override MapperConfiguration Configuration { get; } = new MapperConfiguration(cfg => { - cfg.AddMaps(typeof(When_specifying_open_generic_map_and_reverse_map_with_attribute_and_sourcemember_attribute)); + cfg.AddMaps(typeof(When_specifying_generic_reverse_map_with_sourcemember_attribute)); }); [Fact]