Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ReverseMap and ReplaceMemberName don't work together #832

Closed
brenovieira opened this issue Aug 14, 2015 · 10 comments
Closed

ReverseMap and ReplaceMemberName don't work together #832

brenovieira opened this issue Aug 14, 2015 · 10 comments
Labels
Milestone

Comments

@brenovieira
Copy link

Two of my namespaces have classes with the same property, but with two different names, so in namespace1 it is called UserId and AccountId in namespace2.

public class Test
{
    public string AccountId { get; set; }
}

public class TestDto
{
    public string UserId { get; set; }
}

Since I'm actually mapping the classes in both ways, my AutoMapper config is like that:

Mapper.Initialize(c => {
    c.ReplaceMemberName("Account", "User");
    c.ReplaceMemberName("User", "Account");

   //it works
    c.CreateMap<Test, TestDto>();
    c.CreateMap<TestDto, Test>();

   //it doesn't work
    c.CreateMap<Test, TestDto>().ReverseMap();
});

Mapper.AssertConfigurationIsValid();
  • Creating the map and the reverse map separately works great.
  • Creating the map and the reverse map with reverseMap() doesn't work.

Message error:

Unmapped members were found. Review the types and members below.
Add a custom mapping expression, ignore, add a custom resolver, or modify the source/destination type
========================================================
TestDto -> Test (Source member list)
ConsoleApplication.TestDto -> ConsoleApplication.Test (Source member list)

Unmapped properties:
UserId

As I have several classes, I wouldn't like to use custom .ForMember() map neither call CreateMap twice instead of ReverseMap().

The same issue happens if

  • Create AutoMapper config using with Profiles
  • Create AutoMapper config without Initialize (using Mapper.Configuration.ReplaceMemberName and Mapper.CreateMap<>.ReverseMap)
  • Use full words (c.ReplaceMemberName("AccountId", "UserId");)
@lbargaoanu
Copy link
Member

This seems to work now.

@brenovieira
Copy link
Author

@lbargaoanu , thanks.
I'm using the lastest release 4.0.4.

I'm gonna clone your branch to test in my machine also.

@lbargaoanu
Copy link
Member

On second thought, it seems that the mapping works but AssertConfigurationIsValid fails with the error you saw :)

@brenovieira
Copy link
Author

Hum. I didn't try the mapping itself.

My first unit test is Mapper.AssertConfigurationIsValid();. If it is broken, I stop there.

I created a gist to test the mappings:

  • Using Profile the mapping itself doesn't work.
  • Mapper.AssertConfigurationIsValid(); failed in all tests.

Please see it here: https://gist.github.com/brenovieira/41994109029899a7b488
If you want I can add these tests to AutoMapper repo.

@jbogard jbogard added this to the 4.1.0 milestone Aug 18, 2015
@jbogard
Copy link
Member

jbogard commented Aug 18, 2015

@lbargaoanu yep, failing test! Hooray!

@lbargaoanu
Copy link
Member

Actually there were two separate issues. It seems to work now.
@jbogard I replaced the test to get the redirected properties. It seems to cover both cases, MapFrom and this one.

@brenovieira
Copy link
Author

Great, @lbargaoanu .
I just reviewed the changes and it seems to work.

I believe it'll fix another 2 "issues" I have, as I'm using profiles and reverseMap (all my mappings are two ways mappings).

public IMappingExpression<TDestination, TSource> ReverseMap()
{
    var mappingExpression = _configurationContainer.CreateMap<TDestination, TSource>(TypeMap.Profile, MemberList.Source);

    foreach (var destProperty in TypeMap.GetPropertyMaps().Where(pm => pm.IsIgnored()))
    {
        mappingExpression.ForSourceMember(destProperty.DestinationProperty.Name, opt => opt.Ignore());
    }

    foreach (var includedDerivedType in TypeMap.IncludedDerivedTypes)
    {
        mappingExpression.Include(includedDerivedType.DestinationType, includedDerivedType.SourceType);
    }

    return mappingExpression;
}
  • I ignore several auto implemented readonly properties and I always need to do it in both ways. Something like:
class Source
{
    public string AccountId { get; set; }
    public string IsNew { get { return string.IsNullOrEmpty(AccountId); } }
}
class Destination
{
    public string UserId { get; set; }
    public string IsNew { get { return string.IsNullOrEmpty(UserId); } }
}

CreateMap<Source, Destination>()
    .IgnoreAllPropertiesWithAnInaccessibleSetter()
    .ReverseMap()
        .IgnoreAllPropertiesWithAnInaccessibleSetter();

//in some cases I need to manually ignore property by property calling .ForMember(dest => dest.Property, opt => opt.Ignore()) twice
  • I also have a base abstract class in both namespaces, so I need to call a huge chain of includes in both ways of CreateMap<>() and ReverseMap(). Something like:
class abstract BaseSource
{
    public string AccountId { get; set; }
    public abstract Type Type { get; }
}
class Source1 : BaseSource
{
    public override Type Type { get { return Type.Type1; } }
    //specific properties of concrete class
}
class abstract BaseDestination
{
    public string UserId { get; set; }
    public abstract Type Type { get; }
}
class Destination1 : BaseDestination
{
    public override Type Type { get { return Type.Type1; } }
    //specific properties of concrete class
}

CreateMap<BaseSource, BaseDestination>()
    .Include<Source1, Destination1>()
    .Include<Source2, Destination2>()
    ... //total of 9 concrete classes
    .ReverseMap()
        .Include<Destination1, Source1>()
        .Include<Destination2, Source2>()
        ...;

CreateMap<Source1, Destination1>().ReverseMap();
CreateMap<Source2, Destination2>().ReverseMap();
...

What do you think?

@lbargaoanu
Copy link
Member

Well, the best way to find out is to try them :). What doesn't work as expected, we will fix.

@brenovieira
Copy link
Author

Hahaha. Great.
I'm waiting for the next release. Thanks guys

@jbogard jbogard added the Bug label Aug 20, 2015
@lock
Copy link

lock bot commented May 8, 2019

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@lock lock bot locked as resolved and limited conversation to collaborators May 8, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

3 participants