Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Automapper resolve destination type based on the value of an enum in source type

I'm trying to find a way for Automapper to pick the destination type of a call to map, based on an Enum value set in the Source type...

e.g. Given the following classes:

public class Organisation
{ 
    public string Name {get;set;}
    public List<Metric> Metrics {get;set;}
}

public class Metric
{
   public int NumericValue {get;set;}
   public string TextValue {get;set;}
   public MetricType MetricType {get;set;}
}

public enum MetricType
{
    NumericMetric,
    TextMetric
}

If I have the following object:

var Org = new Organisation { 
    Name = "MyOrganisation",
    Metrics = new List<Metric>{
        new Metric { Type=MetricType.TextMetric, TextValue = "Very Good!" },
        new Metric { Type=MetricType.NumericMetric, NumericValue = 10 }
    }
}

Now, I want to map this to to a viewmodel representation of it which has the classes:

public class OrganisationViewModel
{ 
    public string Name {get;set;}
    public List<IMetricViewModels> Metrics {get;set;}
}

public NumericMetric : IMetricViewModels
{
    public int Value {get;set;}
}

public TextMetric : IMetricViewModels
{
    public string Value {get;set;}
}

The call to AutoMapper.Map will result in an OrganisationViewModel containing one NumericMetric and one TextMetric.

The Automapper call:

var vm = Automapper.Map<Organisation, OrganisationViewModel>(Org);

How would I go about Configuring Automapper to support this? Is this possible? (I hope this question is clear)

Thanks!

like image 538
Paul Avatar asked Sep 26 '12 14:09

Paul


1 Answers

Ok, I'm thinking at the moment the best way to achieve such a thing would be with a TypeConverter for the metric part... Something like:

AutoMapper.Mapper.Configuration
        .CreateMap<Organisation, OrganisationViewModel>();

AutoMapper.Mapper.Configuration
        .CreateMap<Metric, IMetricViewModels>()
        .ConvertUsing<MetricTypeConverter>();

Then the TypeConverter would look something like this:

public class MetricTypeConverter : AutoMapper.TypeConverter<Metric, IMetricViewModel>
{
    protected override IMetricViewModelConvertCore(Metric source)
    {
        switch (source.MetricType)
        {
            case MetricType.NumericMetric :
                return new NumericMetric  {Value = source.NumericValue};

            case MetricType.TextMetric :
                return new TextMetric  {Value = source.StringValue};
        }

    }
}

Does this seem like the right approach here? Any other guidance?

like image 141
Paul Avatar answered Oct 22 '22 11:10

Paul