0

I'm trying to map an object of type A with nested object of type NestedType to an object of type B using AutoMapper, but I've encountered some challenges: If we have same name for:

  1. propertie with type of nested class in class A (source)
  2. string property in class B (result)

Scenario:

We have these types:

  • Source type A:
public class A
{
    public NestedClass AnyName { get; set; }
    // Other properties
    // ...
}
  • Nested type NestedClass:
public class NestedClass
{
    public string Parameter { get; init; }
    // Other properties
    // ...
}
  • Source type B
public class B
{
    public string AnyName { get; set; }
    // Other properties
    // ...
}

And I get an unexpected result when I try to convert like this:

public class MainProfile : Profile
{
    public MainProfile()
    {
        CreateMap<A, B>(MemberList.None)
            .ConstructUsing(x => ConvertToB(x))
            ;
    }

    private B ConvertToB(A a)
    {
        return new B
        {
            AnyName = a.AnyName.Parameter,
            // Other properties
            // ...
        };
    }
}

Example:

For example, I have instance of A:

using AutoMapper;

var a = new A()
{
    AnyName = new() { Parameter = "123" }
};

var configuration = new MapperConfiguration(cfg =>
{
    cfg.AddProfile<MainProfile>();
});

IMapper mapper = configuration.CreateMapper();

var b = mapper.Map<B>(a);

Console.WriteLine(b.AnyName);

Expected result:

123

Actual result:

NestedClass
8
  • Can you verify ConvertToB is called at all? Commented Jan 22 at 11:04
  • Btw having ConvertToB seems to be a convoluted way to have a manual mapping ... Commented Jan 22 at 11:06
  • That said, have you tried adding a CreateMap<NestedClass, string> ? But I guess it's not that easy in the actual code, right? Commented Jan 22 at 11:08
  • Yeah, I can do mark this method as static and do like this: var b2 = MainProfile.ConvertToB(a); and it works, but I use it in work in more hard case and it's a problem to use this method instead automapper Commented Jan 22 at 11:14
  • Ok, I see. So, are you able to set a breakpoint or make a log entry or even create a unit test (which I would recommend) to verify the ConvertToB is called? Commented Jan 22 at 11:22

1 Answer 1

1

It looks like you're trying to flatten the nested type as part of your mapping. AutoMapper will do this automatically if you name your properties in a certain way, without the need for your ConvertToB method.

using System;
using AutoMapper;
                    
public class Program
{
    public static void Main()
    {
        var a = new A()
        {
            AnyName = new() { Parameter = "123" }
        };

        var configuration = new MapperConfiguration(cfg =>
        {
            cfg.AddProfile<MainProfile>();
        });

        IMapper mapper = configuration.CreateMapper();

        var b = mapper.Map<B>(a);

        Console.WriteLine(b.AnyNameParameter);
    }
}

public class A
{
    public NestedClass AnyName { get; set; }
}

public class B
{
    public string AnyNameParameter { get; set; }
}

public class NestedClass
{
    public string Parameter { get; init; }
}

public class MainProfile : Profile
{
    public MainProfile()
    {
        CreateMap<A, B>();
    }
}

https://dotnetfiddle.net/34v1SA

AutoMapper does that by convention, but if you don't want to change the parameter name you can use ForMember and MapFrom which gives you some more control over your mappings if needed.

public MainProfile()
{
    CreateMap<A, B>()
        .ForMember(d => d.Parameter, opt => opt.MapFrom(s => s.AnyName.Parameter));
}

https://docs.automapper.org/en/latest/Flattening.html

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

1 Comment

Thanks for answer. Yeah, it worked for me in both variants. It was strange for me, what automapper maps this props, when I use ConstructUsing. But now I understand. It was happened, because Flatenning Thank you

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.