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
:
- 将 json 字符串反序列化为
ISubscriptionCriteria
对象。
- 根据
SubscriptionTypeId
. 映射到 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)));
}
}
}
如果你有更优雅的解决方案请分享,我很想学习!
我有这样的来源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
:
- 将 json 字符串反序列化为
ISubscriptionCriteria
对象。 - 根据
SubscriptionTypeId
. 映射到
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)));
}
}
}
如果你有更优雅的解决方案请分享,我很想学习!