2

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:

  1. De-serializing the json string to a ISubscriptionCriteria object.
  2. Mapping to the correct concrete type for 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)); })
    );

1 Answer 1

2

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!

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.