3

I have the following code.
All of the fields map nicely from the source to the destination object.
However, there is one field in the destination object that I will need to compute.

For example:
DestinationObj.Status can be set depending on certain fields from the SourceObj.

If I were to write code, it would look similar to:

foreach (var rec in listData)
{
    string status;

    if (!String.IsNullOrEmpty(rec.Field1))
    {
        status = "Stage 1";
    }

    if (!String.IsNullOrEmpty(rec.Field2))
    {
        status = "Stage 2";
    }

    if (!String.IsNullOrEmpty(rec.Field3))
    {
        status = "Stage 3";
    }
}

Can I do something similar in AutoMapper?

var config = new MapperConfiguration(c =>
{
    c.CreateMap<SourceObj, DestinationObj>()
        .ForMember(x => x.Status, m => m.MapFrom([Not sure at this point]));
});

EDIT:

List<destinationObj> destinObj = new List<destinationObj>();

foreach (var rec in listSourceObject)
{
    destinationObj do = new destinationObj();
    // Manually map all of the fields...

    string status;

    if (!String.IsNullOrEmpty(rec.Field1))
    {
        do.status = "Stage 1";
    }

    if (!String.IsNullOrEmpty(rec.Field2))
    {
        do.status = "Stage 2";
    }

    if (!String.IsNullOrEmpty(rec.Field3))
    {
        do.status = "Stage 3";
    }

    destinObj.Add(do);
}
Lauren Rutledge
  • 1,195
  • 5
  • 18
  • 27
John Doe
  • 3,053
  • 17
  • 48
  • 75

2 Answers2

6

The easiest way to do this is to move your method into your mapper class. You can then access that method within your .MapFrom().

var config = new MapperConfiguration(c =>
{
    c.CreateMap<SourceObj, DestinationObj>()
        .ForMember(dest => dest.Status, opt => opt.MapFrom(src => MapStatus(src)));

});

private string MapStatus(SourceObject source)
{
    // Whatever that foreach loop actually does.
}

For more info, see Custom Value Resolvers

Bumbl3b33
  • 5
  • 1
  • 4
krillgar
  • 12,596
  • 6
  • 50
  • 86
3

Suggested solutions with MapFrom() and workarounds for expressions are not entirely correct. MapFrom() (as AutoMapper: What is the difference between MapFrom and ResolveUsing? suggests) is smarter, so it can handle nested PropertyExpressions.

To handle regular functions for mapping values, you should use ResolveUsing(), which accepts a Func<>, so you can enter the code directly and there is no need to modify the call to be expressed as Expression<Func<>>.

Community
  • 1
  • 1
kiziu
  • 1,111
  • 1
  • 11
  • 15
  • Since [version 8](https://docs.automapper.org/en/stable/8.0-Upgrade-Guide.html#resolveusing), `ResolveUsing` has been consolidated with `MapFrom`. You now have an overload that takes a `Func<>`. – martinoss Jul 14 '22 at 11:35