Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Access the destination property name to be mapped in IValueResolver

Tags:

c#

automapper

I'd like to reuse the same IValueResolver for several properties for the same class, all three properties to be mapped pass for the same process, so I don't want to repeat a code that could be almost the same.

I want to do something like this:

CreateMap<AlertLine, AlertLineDto>()
                .ForMember(dest => dest.BusinessArea, opt => opt.MapFrom<MyResolver>())

CreateMap<AlertLine, AlertLineDto>()
                .ForMember(dest => dest.Division, opt => opt.MapFrom<MyResolver>())

CreateMap<AlertLine, AlertLineDto>()
                .ForMember(dest => dest.SubDivision, opt => opt.MapFrom<MyResolver>())


public class MyResolver : IValueResolver<AlertLine, AlertLineDto, string>
    {
        private readonly ICatalogService _catalogService;
        public BusinessAreaResolver(ICatalogService catalogService)
        {
            _catalogService = catalogService;
        }
        public string Resolve(AlertLine source, AlertLineDto destination, string destMember, ResolutionContext context)
        {
            // How to access the destination property name to be mapped?
            // BusinessArea, Division, SubDivision, and so on...

            string val = string.Empty;
            var variant = JsonSerializer.Deserialize<AddlInformation>(source.AddlDimension);
            if (variant.BUSINESS_AREA_ID > 0)
            {
                var businessArea = _catalogService.GetCachedBusinessAreaById(variant.BUSINESS_AREA_ID);
                val = businessArea?.Description;

            }
            return val;
        }

    }
like image 333
pedrommuller Avatar asked Dec 06 '25 04:12

pedrommuller


1 Answers

Try using IMemberValueResolver instead of IValueResolver

Send the property name instead of the actual source value if the logic varies for different member.

CreateMap<AlertLine, AlertLineDto>()
.ForMember(
    dest => dest.BusinessArea,
    opt => opt.MapFrom<MyResolver, string>(p => "BusinessArea"))) 
    //opt => opt.MapFrom<MyResolver, string>(source => source.BusinessArea))
.ForMember(
    dest => dest.Division,
    opt => opt.MapFrom<MyResolver, string>(p => "Division")))
   //opt => opt.MapFrom<MyResolver, string>(source => source.Division))
.ForMember(
    dest => dest.SubDivision,
    opt => opt.MapFrom<MyResolver, string>(p => "SubDivision"));
    //opt => opt.MapFrom<MyResolver, string>(source => source.SubDivision))

The propertyName parameter will help you identify which mapping is currently called based on the value of the parameter. The returnValue will be mapped to the appropriate destination member

public class MyResolver : IMemberValueResolver<AlertLine, AlertLineDto, string, string>
{    
    public string Resolve(AlertLine source, AlertLineDto destination, string propertyName, string destMember, ResolutionContext context)
    {
        string sourceValue = string.Empty;
        string returnValue = string.Empty;

        switch (propertyName)
        {
            case "BusinessArea":
                 sourceValue = source.BusinessArea;
                 //returnValue = Some Logic here
                break;
            case "Division":
                sourceValue = source.Division;
                //returnValue = Some Logic here
                break;
            case "SubDivision":
                sourceValue = source.SubDivision;
                //returnValue = Some Logic here
                break;

            default:
                break;
        }          
        return returnValue;
    }    
}
like image 102
Akshay G Avatar answered Dec 08 '25 17:12

Akshay G



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!