agileobjects/AgileMapper

Question - mapping multiple classes to a single one ?

Alysaar opened this issue · 5 comments

Hello,

AgileMapper has worked wonders for me when mapping a source to different destinations but now I am having trouble with the other way around.

I am trying to map two different source instances to two properties of a destination instance. Normally I would use OnTo but I am using the ThrowIfAnyMappingPlanIsIncomplete option and it seems like they are incompatible.

Here is an example : https://dotnetfiddle.net/aVzwph

Is there a better way of doing this ?

Hello!

Glad to hear you've found the mapper useful! :)

There's been other holes found in mapping validation lately, and I think there might be some missing functionality here. This:

mapper.WhenMapping
    .From<SourceClass>().ToANew<DestinationClass>()
    .Map((source, _) => source.TheCat).To(dest => dest.PetNames)
    .And
    .Map((source, _) => source.TheDog).To(dest => dest.PetNames);

...errors because we're setting two different data sources for the same target member, and I think that's probably what it should do - maybe we should be able to do this:

mapper.WhenMapping
    .From<SourceClass>().ToANew<DestinationClass>()
    .Map((source, _) => source.TheCat).To(dest => dest.PetNames)
    .Then
    .Map((source, _) => source.TheDog).To(dest => dest.PetNames);

...with .Then indicating the two data sources are intended to be supplied sequentially, and there's been no mistake in configuring two different sources for the same member?

In the meantime, there's this:

mapper.WhenMapping
    .From<SourceClass>().ToANew<DestinationClass>()
    .Map((source, _) => source.TheCat).To(dest => dest.PetNames);

mapper.WhenMapping
    .From<SourceClass>().ToANew<PetNames>()
    .Map((source, _) => source.TheDog).ToTarget();

But that fails validation because the mapper isn't figuring out that applying TheDog to PetNames using ToTarget gives PetNames.DogName a matching source. That's a bug, and I'll sort it out.

Thanks for the feedback, and happy new year!

Steve

Thank you for your reply, I will work on a workaround on my side.

I like your .Then idea, but what would you think of doing this instead :

mapper.WhenMapping
    .From<SourceClass>().ToANew<DestinationClass>()
    .Map((source, _) => source.TheCat).To(dest => dest.PetNames)
    .And
    .Map((source, _) => source.TheDog).OnTo(dest => dest.PetNames);

This would reuse your OnTo expression, and the meaning seems similar to me.

Cheers.

Hello again!

.ToTarget() configurations are taken into account when validating mapping plans in the latest 1.7 release branch code - preview release to follow.

I'm going to include the Then sequential mapping syntax as well - I think that'll be simpler to implement than using OnTo because switching from object creation to merging within a mapping would be pretty tricky - it also might not get the behaviour we want here, because merging checks existing values aren't populated before mapping.

Thanks again for the feedback - stay safe!

Steve

Sequential data source configuration is included in v1.7-preview1, which is now available on NuGet.

mapper.WhenMapping
    .From<SourceClass>().ToANew<DestinationClass>()
    .Map((source, _) => source.TheCat)
    .Then((source, _) => source.TheDog)
    .To(dest => dest.PetNames);

Cheers!

v1.7 is now available on NuGet.

Thanks again!