AutoMapper recursive

Posted by fra on Stack Overflow See other posts from Stack Overflow or by fra
Published on 2010-05-07T06:55:51Z Indexed on 2010/05/07 6:58 UTC
Read the original article Hit count: 1331

Filed under:

Hi!

I would like to make a deep copy of a complex object tree using AutoMapper. The problem is that for each member I would like to construct a new object and then map it, and not simply copying the existing one. Here it is an example: public abstract class Test { public Test() { this.Id = Guid.NewGuid(); }

    public Guid Id { get; private set; }
}

public class OuterTest : Test
{
    public InnerTest Inner { get; set; }
}

public class InnerTest : Test
{
    public int Value { get; set; }
}

and how to test it:

OuterTest outerDest = Mapper.Map<OuterTest, OuterTest>(outerSource);
            System.Diagnostics.Debug.WriteLine("InnerSource id: " + innerSource.Id);
            System.Diagnostics.Debug.WriteLine("InnerSource value: " + innerSource.Value);
            System.Diagnostics.Debug.WriteLine("OuterSource id: " + outerSource.Id);
            System.Diagnostics.Debug.WriteLine("OuterDest id: " + outerDest.Id);
            System.Diagnostics.Debug.WriteLine("OuterDest.Inner id: " + outerDest.Inner.Id);
            System.Diagnostics.Debug.WriteLine("OuterDest.Inner value: " + outerDest.Inner.Value);

This is the result from the output window:

InnerSource id: a60fda37-206a-40a8-a7f8-db480149c906
InnerSource value: 2119686684
OuterSource id: 7486899e-2da8-4873-9160-d6096b555c73
OuterDest id: 7486899e-2da8-4873-9160-d6096b555c73
OuterDest.Inner id: a60fda37-206a-40a8-a7f8-db480149c906
OuterDest.Inner value: 2119686684

The problem is thet the object innerSource is always the same instance as outerDest.Inner (I verified through MakeObjectId of VS debugger) but I would like them to be two different instances.

How could I create a recursive map with this behavior? I tried creating a custom IValueResolver like the following, without success.

public class AutoMapperNewObjectResolver : IValueResolver
    {
        public ResolutionResult Resolve(ResolutionResult source)
        {
            object resolved;
            if (source.Value != null)
            {
                object instance = Activator.CreateInstance(source.MemberType);
                resolved = Mapper.Map(source.Value, instance, source.MemberType, source.MemberType);
            }
            else
            {
                resolved = null;
            }
            ResolutionResult result = source.New(resolved, source.Context.DestinationType);
            return result;

} }

and configured like this:

Mapper.CreateMap<OuterTest, OuterTest>()
                .ForMember(d => d.Inner, o => o.ResolveUsing<AutoMapperNewObjectResolver>().FromMember(src => src.Inner));

Any help appreciated, thank you

© Stack Overflow or respective owner

Related posts about automapper