mapping to existing destination object

1,156 views
Skip to first unread message

blaz

unread,
Jun 15, 2010, 6:16:35 AM6/15/10
to AutoMapper-users
I've also ran into some problems with AutoMapper when mapping values
to existing object. Basically I can't configure nested mapping to map
correctly to new destination object and to map to existing destination
object. Even when I limit mapping only to existing object there are
still problems.

Ideally single mapping configuration should provide mapping to new
destination object and to existing destination object. When mapping
nested properties to existing destination object, mapping should keep
nested destination objects when appropriate. but it should also create
new nested destination objects or remove existing ones when this is
required.

I have modified nested mappings sample to ilustrate what I mean:

using AutoMapper;
using NBehave.Spec.NUnit;
using NUnit.Framework;

namespace AutoMapperSamples
{
namespace NestedMappings
{
[TestFixture]
public class Sample
{
public class OuterSource
{
public int Value { get; set; }
public InnerSource Inner { get; set; }
}

public class InnerSource
{
public int OtherValue { get; set; }
}

public class OuterDest
{
public int Value { get; set; }
public InnerDest Inner { get; set; }
}

public class InnerDest
{
public int OtherValue { get; set; }
}

[TestFixtureSetUp]
public void PrepareMapping()
{
Mapper.Reset();
Mapper.CreateMap<OuterSource, OuterDest>()
.ForMember(d => d.Value, opt => opt.Condition(src
=> src.Value != 77));
Mapper.CreateMap<InnerSource, InnerDest>()
.ForMember(d => d.OtherValue, opt =>
opt.Condition(src => src.OtherValue != 55));
Mapper.AssertConfigurationIsValid();
}

[Test]
public void Example()
{
var source = new OuterSource
{
Value = 5,
Inner = new InnerSource
{OtherValue = 15}
};

var dest = Mapper.Map<OuterSource, OuterDest>(source);

dest.Value.ShouldEqual(5);
dest.Inner.ShouldNotBeNull();
dest.Inner.OtherValue.ShouldEqual(15);
}


[Test]
public void OverwriteDestination()
{
Mapper.CreateMap<OuterSource, OuterDest>()
.ForMember(d => d.Value, opt => opt.Condition(src
=> src.Value != 77));
Mapper.CreateMap<InnerSource, InnerDest>()
.ForMember(d => d.OtherValue, opt =>
opt.Condition(src => src.OtherValue != 55));
Mapper.AssertConfigurationIsValid();

var source = new OuterSource
{
Value = 77,
Inner = new InnerSource
{OtherValue = 55}
};

var dest = Mapper.Map(source,
new OuterDest
{
Value = 6,
Inner = new InnerDest
{OtherValue = 532,},
});

dest.Value.ShouldEqual(6);
dest.Inner.ShouldNotBeNull();
dest.Inner.OtherValue.ShouldEqual(532);
}

[Test]
public void OverwriteDestinationCreateInner()
{
var source = new OuterSource
{
Value = 5,
Inner = new InnerSource
{OtherValue = 15}
};

var dest = Mapper.Map(source, new OuterDest {Value =
4});

dest.Value.ShouldEqual(5);
dest.Inner.ShouldNotBeNull();
dest.Inner.OtherValue.ShouldEqual(15);
}

[Test]
public void OverwriteDestinationRemoveInner()
{
var source = new OuterSource
{
Value = 5,
Inner = new InnerSource
{OtherValue = 15}
};

var dest = Mapper.Map(source, new OuterDest {Value =
4, Inner = new InnerDest()});

dest.Value.ShouldEqual(5);
dest.Inner.ShouldBeNull();
}
}
}
}

Jimmy Bogard

unread,
Jun 15, 2010, 8:31:52 AM6/15/10
to automapp...@googlegroups.com
So this is part of the reason that reverse mapping is taking a while to put in.  It's those "when appropriate" decisions that vary wildly from user to user and scenario to scenario.  I've had requests like:

- Always clear collections
- Never clear collections, only add
- Never instantiate new objects if the object already exists
- Always instantiate new objects, no matter what
- Collections are encapsulated (i.e., the List<T> is not public), so you need to find the AddFoo method for the corresponding GetFoos() one
- Only instantiate objects if it's of a certain base type (Entity), but ALWAYS overwrite other kinds of objects
- Only set some of the members you find from the original destination type

etc

I do like to see these examples, as our systems don't have the need for reverse mapping.  We're getting to the point where we don't expose setters on our domain objects.  Any new insight in to what folks need would be fantastic.

Thanks,

Jimmy


--
You received this message because you are subscribed to the Google Groups "AutoMapper-users" group.
To post to this group, send email to automapp...@googlegroups.com.
To unsubscribe from this group, send email to automapper-use...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/automapper-users?hl=en.


Reply all
Reply to author
Forward
0 new messages