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..3f0a0968cd 100644 --- a/src/UnitTests/AttributeBasedMaps.cs +++ b/src/UnitTests/AttributeBasedMaps.cs @@ -77,6 +77,82 @@ public void Should_validate_successfully() } } + public class When_specifying_reverse_map_with_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_reverse_map_with_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_generic_reverse_map_with_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_generic_reverse_map_with_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