代码之家  ›  专栏  ›  技术社区  ›  pedrommuller

访问要在IValueResolver中映射的目标属性名称

  •  0
  • pedrommuller  · 技术社区  · 3 年前

    我想对同一个类的几个属性重用同一个IValueResolver,要映射的所有三个属性都会传递给同一个进程,所以我不想重复几乎相同的代码。

    我想这样做:

    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;
            }
    
        }
    
    0 回复  |  直到 3 年前
        1
  •  1
  •   Akshay G    3 年前

    尝试使用 IMemberValueResolver 而不是 IValueResolver

    如果不同成员的逻辑不同,则发送属性名而不是实际的源值。

    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))
    

    这个 propertyName 参数将帮助您根据参数的值确定当前调用的映射。这个 returnValue 将映射到相应的目标成员

    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;
        }    
    }