Amit Kumar Ghosh
Amit Kumar Ghosh

Reputation: 3726

Automapper - Add to List conditionally

The situation is -

public class One
{
    public string S1 { get;set; }
    public string S2 { get;set; }
    public string S3 { get;set; }
    public string S4 { get;set; }
}

public class Two
{
    public List<string> List1 { get;set; }
}

Now what I want is to populate the list inside Two with the non-null property values of One.

Is there anyway / work-around to achieve this using AutoMapper ?

Upvotes: 1

Views: 3323

Answers (2)

stuartd
stuartd

Reputation: 73293

If that is the only mapping you want to do between the classes, you can use a custom type converter: this then takes complete charge of the mapping between the objects.

public class OneTwoTypeResolver : TypeConverter<One, Two>
{
    protected override Two ConvertCore(One source)
    {
        Two two = new Two {List1 = new List<string>()};

        if (source.S1 != null)
            two.List1.Add(source.S1);

        if (source.S2 != null)
            two.List1.Add(source.S2);

        if (source.S3 != null)
            two.List1.Add(source.S3);

        if (source.S4 != null)
            two.List1.Add(source.S4);

        return two;
    }
}

You tell AutoMapper to use this class when mapping between the classes:

Mapper.CreateMap<One, Two>().ConvertUsing<OneTwoTypeResolver>();

Then this test will pass:

public void Test()
{
    One one = new One {S2 = "OneTwoThreeFour"};
    Two two = Mapper.Map<One, Two>(one);
    Assert.AreEqual(1, two.List1.Count);
    Assert.AreEqual("OneTwoThreeFour", two.List1.Single());
}

Upvotes: 2

Pawel Maga
Pawel Maga

Reputation: 5807

In this case you can create your own custom value resolver:

public class CustomResolver : ValueResolver<One, List<string>>
{
    protected override List<string> ResolveCore(One source)
    {
        var result = new List<string>();

        //your logic
        if (!string.IsNullOrWhiteSpace(source.S1))
            result.Add(source.S1);

        if (!string.IsNullOrWhiteSpace(source.S2))
            result.Add(source.S2);

        if (!string.IsNullOrWhiteSpace(source.S3))
            result.Add(source.S3);

        if (!string.IsNullOrWhiteSpace(source.S4))
            result.Add(source.S4);

        return result;
    }
}

Mapping configuration:

Mapper.CreateMap<One, Two>()
    .ForMember(dest => dest.List1, opt => opt.ResolveUsing<CustomResolver>());

In this way you are able to configure mappings for specific properties

Upvotes: 2

Related Questions