AutoMapper - 将 Json 字符串 属性 映射到基于接口的对象

AutoMapper - Map Json string property to interface based object

我有这样的来源class:

public partial class Source
{
    ...
    public int ScheduleBaseId { get; set; }
    public int ScheduleIncrement { get; set; }
    public int SubscriptionTypeId { get; set; } // <- Determines the concrete class to map to
    public string SubscriptionCriteriaJson { get; set; } // <- Map to interface class
    ...
}

我正在映射到这个目的地 class:

public class Dest
{
    ...
    public Schedule Schedule { get; set; }
    public ISubscriptionCriteria SubscriptionCriteria { get; set; }
    ...
}

我想将 Source.SubscriptionCriteriaJson 属性 映射到使用接口的 Dest.SubscriptionCriteria。接口的具体 class 可以使用 Source.SubscriptionTypeId 确定。我试图在这里解决两个问题以映射到 SubscriptionCriteria:

  1. 将 json 字符串反序列化为 ISubscriptionCriteria 对象。
  2. 根据 SubscriptionTypeId.
  3. 映射到 ISubscriptionCriteria 的正确具体类型

关于我如何在 AutoMapper 中实现这一点的任何想法/指示?我是 AutoMapper 的新手,所以我还在摸索。

这是我目前为止剩下的映射:

var config = new MapperConfiguration(
    cfg => cfg.CreateMap<Source, Dest>()
        .ForMember(dest => dest.Schedule, opt => { opt.MapFrom(src => new Schedule((ScheduleBaseEnum)src.ScheduleBaseId, src.ScheduleIncrement)); })
    );

我通过以下方式解决了这个问题:

public class AutoMapperProfileConfiguration : Profile
{
    public AutoMapperProfileConfiguration()
        : this("MyProfile")
    {
    }

    protected AutoMapperProfileConfiguration(string profileName)
        : base(profileName)
    {
        CreateMap<Source, Dest>()
            .ForMember(dest => dest.Schedule, opt =>
            {
                opt.MapFrom(src => new Schedule((ScheduleBaseEnum)src.ScheduleBaseId, src.ScheduleIncrement));
            })
            .ForMember(dest => dest.SubscriptionCriteria, opt =>
            {
                opt.MapFrom(src => (ISubscriptionCriteria)JsonConvert.DeserializeObject(src.SubscriptionCriteriaJson, GetSubscriptionCriteriaType((SubscriptionTypeEnum)src.SubscriptionTypeId)));
            });
    }

    private Type GetSubscriptionCriteriaType(SubscriptionTypeEnum type)
    {
        switch (type)
        {
            case SubscriptionTypeEnum.SomeType1:
                return typeof(SomeType1);
            case SubscriptionTypeEnum.SomeType2:
                return typeof(SomeType2);
            ...
            default:
                throw new NotImplementedException(string.Format("SubscriptionType of {0} is not implemented.", Enum.GetName(typeof(SubscriptionTypeEnum), type)));
        }
    }
}

如果你有更优雅的解决方案请分享,我很想学习!