Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions src/AutoMapper/Configuration/MappingExpression.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,7 @@ public IMappingExpression ReverseMap()
{
var reversedTypes = new TypePair(Types.DestinationType, Types.SourceType);
var reverseMap = new MappingExpression(reversedTypes, MemberList.None);
if(!reversedTypes.IsGenericTypeDefinition)
{
reverseMap.MemberConfigurations.AddRange(MemberConfigurations.Select(m => m.Reverse()).Where(m => m != null));
}
reverseMap.MemberConfigurations.AddRange(MemberConfigurations.Select(m => m.Reverse()).Where(m => m != null));
ReverseMapExpression = reverseMap;
reverseMap.IncludeMembers(MapToSourceMembers().Select(m => m.DestinationMember.Name).ToArray());
foreach(var includedMemberName in IncludedMembersNames)
Expand Down
20 changes: 18 additions & 2 deletions src/AutoMapper/Configuration/MemberConfigurationExpression.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ namespace AutoMapper.Configuration
public class MemberConfigurationExpression<TSource, TDestination, TMember> : IMemberConfigurationExpression<TSource, TDestination, TMember>, IPropertyMapConfiguration
{
private LambdaExpression _sourceMember;
private string _sourceMemberName;
private readonly Type _sourceType;
protected List<Action<PropertyMap>> PropertyMapActions { get; } = new List<Action<PropertyMap>>();

Expand Down Expand Up @@ -123,6 +124,7 @@ internal void MapFromUntyped(LambdaExpression sourceExpression)
public void MapFrom(string sourceMemberName)
{
_sourceType.GetFieldOrProperty(sourceMemberName);
_sourceMemberName = sourceMemberName;
PropertyMapActions.Add(pm => pm.MapFrom(sourceMemberName));
}

Expand Down Expand Up @@ -340,8 +342,22 @@ private void Apply(PropertyMap propertyMap)
public LambdaExpression SourceExpression => _sourceMember;
public LambdaExpression GetDestinationExpression() => MemberAccessLambda(DestinationMember);

public IPropertyMapConfiguration Reverse() =>
PathConfigurationExpression<TDestination, TSource, object>.Create(_sourceMember, GetDestinationExpression());
public IPropertyMapConfiguration Reverse()
{
var destinationType = DestinationMember.DeclaringType;
if (_sourceMemberName != null)
{
var sourceMember = _sourceType.GetFieldOrProperty(_sourceMemberName);
var reversedMemberConfiguration = new MemberConfigurationExpression<TDestination, TSource, object>(sourceMember, destinationType);
reversedMemberConfiguration.MapFrom(DestinationMember.Name);
return reversedMemberConfiguration;
}
if (destinationType.IsGenericTypeDefinition) // .ForMember("InnerSource", o => o.MapFrom(s => s))
{
return null;
}
return PathConfigurationExpression<TDestination, TSource, object>.Create(_sourceMember, GetDestinationExpression());
}

public void DontUseDestinationValue() => SetUseDestinationValue(false);
}
Expand Down
59 changes: 59 additions & 0 deletions src/UnitTests/ReverseMapping.cs
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,34 @@ public void Should_unflatten()
}
}

public class ReverseMapFromSourceMemberName : AutoMapperSpecBase
{
public class Source
{
public int Value { get; set; }
}

public class Destination
{
public int Value2 { get; set; }
}

protected override MapperConfiguration Configuration => new MapperConfiguration(cfg =>
{
cfg.CreateMap<Source, Destination>()
.ForMember(d => d.Value2, o => o.MapFrom("Value"))
.ReverseMap();
});

[Fact]
public void Should_reverse_map_ok()
{
Destination destination = new Destination { Value2 = 1337 };
Source source = Mapper.Map<Source>(destination);
source.Value.ShouldBe(1337);
}
}

public class ReverseDefaultFlatteningWithIgnoreMember : AutoMapperSpecBase
{
public class Order
Expand Down Expand Up @@ -594,4 +622,35 @@ public void Should_create_a_map_with_the_reverse_items()
_source.Value.ShouldBe(10);
}
}

public class When_reverse_mapping_open_generics_with_MapFrom : AutoMapperSpecBase
{
public class Source<T>
{
public T Value { get; set; }
public string StringValue { get; set; }
}
public class Destination<T>
{
public T Value2 { get; set; }
public string StringValue2 { get; set; }
}

protected override MapperConfiguration Configuration { get; } = new MapperConfiguration(cfg =>
{
cfg.CreateMap(typeof(Source<>), typeof(Destination<>))
.ForMember("Value2", o => o.MapFrom("Value"))
.ForMember("StringValue2", o => o.MapFrom("StringValue"))
.ReverseMap();
});

[Fact]
public void Should_reverse_map_ok()
{
Destination<int> destination = new Destination<int> { Value2 = 1337, StringValue2 = "StringValue2" };
Source<int> source = Mapper.Map<Destination<int>, Source<int>>(destination);
source.Value.ShouldBe(1337);
source.StringValue.ShouldBe("StringValue2");
}
}
}