C# AutoMapper Conditional Mapping based upon targe

2019-04-21 03:21发布

问题:

Please can any one advise how to use conditional mapping in AutoMapper to map a value in the TARGET object from a SOURCE object based upon an existing TARGET property value?

So my source class is:

public class UserDetails
{
    public String Nickname { get; set; }
}

My target class is:

public class ProfileViewModel
{
    public Boolean NicknameIsVisible { get; set;
    public String Nickname { get; set; }
}

I want to set the "Nickname" property value in the TARGET to match the "Nickname" property value in the SOURCE only if the target property "NicknameIsVisible" value is already set to TRUE, otherwise I want to set the TARGET "Nickname" property value to an empty string.

I was trying something like this (which wont compile )...

Mapper.CreateMap<UserDetails, ProfileViewModel>()
.ForMember(
            destination => destination.Nickname,
            option => option.
                .MapFrom(
                    source => source.NicknameIsVisible ? 
                    source.Nickname :
                    String.Empty)
);

but "NicknameIsVisible" is not a property of my SOURCE but of my TARGET.

BTW, My ProfileViewModel is bound to three entities using Owain Wragg's method (http://consultingblogs.emc.com/owainwragg/archive/2010/12/22/automapper-mapping-from-multiple-objects.aspx) and it is another entity that gives the value to the "NicknameIsVisible" property.

Please can anyone suggest the right syntax to use for this problem?

回答1:

Try this:

Mapper.CreateMap<UserDetails, ProfileViewModel>()
.ForMember(
        destination => destination.Nickname,
        option => 
        {
            option.Condition(rc => 
            {
                var profileViewModel = (ProfileViewModel)rc.InstanceCache.First().Value;
                return profileViewModel.NicknameIsVisible;
            });

            option.MapFrom(source => source.Nickname);
        }
);


回答2:

Using devduder's example I now have the following code which compiles:

.ForMember(
    destination => destination.Nickname,
    option => 
    {
        option.Condition(resolutionContext =>
            (resolutionContext.InstanceCache.First().Value as ProfileViewModel).NicknameIsVisible);
        option.MapFrom(source => source.Nickname);
    }
);

However although it compiles and runs through it is not populating the destination.Nickname with anything.

Edit: I had to change the order of my mapping so the preferences object (which has the values for the "NicknameIsVisible" property was mapped first so the value was available to test against!)

So the call to my three-way mapping was:

var profileViewModel = EntityMapper.Map<ProfileViewModel>(preferences, member, account);

This ensured that the preferences object was mapped to the ViewModel first, then the conditional mapping for the account object could take place once the values had been set.

So this is my solution, but I cannot up-vote my own answer!