Antialiasing without prefix names in child object in AutoMapper

Consider these classes as a source:

public class SourceParent
{
    public int X { get; set; }
    public SourceChild1 Child1 { get; set; }
    public SourceChild2 Child2 { get; set; }
}

public class SourceChild1
{
    public int A { get; set; }
    public int B { get; set; }
    public int C { get; set; }
    public int D { get; set; }
}

public class SourceChild2
{
    public int I { get; set; }
    public int J { get; set; }
    public int K { get; set; }
    public int L { get; set; }
}

      

I am trying to match source to destination like this:

public class Destination
{
    public int X { get; set; }

    public int A { get; set; }
    public int B { get; set; }
    public int C { get; set; }
    public int D { get; set; }

    public int I { get; set; }
    public int J { get; set; }
    public int K { get; set; }
    public int L { get; set; }
}

      

Well using this config the mapping can be done:

Mapper.CreateMap<SourceParent, Destination>()
    .ForMember(d => d.A, opt => opt.MapFrom(s => s.Child1.A))
    .ForMember(d => d.B, opt => opt.MapFrom(s => s.Child1.B))
    .ForMember(d => d.C, opt => opt.MapFrom(s => s.Child1.C))
    .ForMember(d => d.D, opt => opt.MapFrom(s => s.Child1.D))
    .ForMember(d => d.I, opt => opt.MapFrom(s => s.Child2.I))
    .ForMember(d => d.J, opt => opt.MapFrom(s => s.Child2.J))
    .ForMember(d => d.K, opt => opt.MapFrom(s => s.Child2.K))
    .ForMember(d => d.L, opt => opt.MapFrom(s => s.Child2.L));

      

Also, when a child class has many properties, all of which have the same name with the parent, this is not a clean way.

Ideally, I would like to tell AutoMapper to also use Source.Child1 and Source.Child2 and map all matching property names to the target (instead of specifying each individual property); something like that:

Mapper.CreateMap<SourceParent, Destination>()
    .AlsoUseSource(s => s.Child1)
    .AlsoUseSource(s => s.Child2);

      

+3


source to share


1 answer


You can use .ConstructUsing

to accomplish this. It's not the cleanest thing in the world, but it will work:

/* Map each child to the destination */
Mapper.CreateMap<SourceChild1, Destination>();
Mapper.CreateMap<SourceChild2, Destination>();

Mapper.CreateMap<SourceParent, Destination>()
    .ConstructUsing(src =>
    {
        /* Map A-D from Child1 */
        var dest = Mapper.Map<Destination>(src.Child1);

        /* Map I-L from Child2 */
        Mapper.Map(src.Child2, dest);

        return dest;
    });
/* X will be mapped automatically. */

      

This should display all properties successfully.



Unfortunately, the call .AssertConfigurationIsValid

will fail, since the properties I

- L

are not displayed in the target type to be displayed from SourceParent

Destination

.

You could, of course, write a call .Ignore

for each of them, but that kind of cancels out the goal of getting rid of the nested display calls.

Another option would be to use this awesome answer to ignore the unselected properties for each of the mappings.

+3


source







All Articles