I have a source class like this:
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
...
}
Which I'm mapping to this destination class:
public class Dest
{
...
public Schedule Schedule { get; set; }
public ISubscriptionCriteria SubscriptionCriteria { get; set; }
...
}
I'd like to map the Source.SubscriptionCriteriaJson
property to Dest.SubscriptionCriteria
which uses an interface. The concrete class for the interface can be determined using Source.SubscriptionTypeId
. There's two issues in tandem I'm trying to resolve here for mapping to SubscriptionCriteria
:
ISubscriptionCriteria
object.ISubscriptionCriteria
based on SubscriptionTypeId
.Any ideas / pointers how I achieve this in AutoMapper? I'm new to AutoMapper so am still feeling my way around.
This is what I have so far for the rest of the mapping:
var config = new MapperConfiguration(
cfg => cfg.CreateMap<Source, Dest>()
.ForMember(dest => dest.Schedule, opt => { opt.MapFrom(src => new Schedule((ScheduleBaseEnum)src.ScheduleBaseId, src.ScheduleIncrement)); })
);
I solved this in the following way:
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)));
}
}
}
If there's a more elegant solution you can think of please share I'm keen to learn!