AutoMapper: Unexpected behavior for CustomValueResolver
I’m experiencing an unexpected (for me, at least) behavior mapping a DTO to an existing Entity:
Entity ret = Mapper.Map(dto, existingEntity)
I’ve built a simple (I hope) sample that shows the behavior (using both Automapper 5.2.0 AND 6.1.0).
Sample code here.
Basically, my aggregate is a master with a list of details, where both master and detail entity implements an interface that defines a property (a relation to a separate entity).
This relation is far complicated (not in the sample, of course), so I’ve defined a CustomMemberValueResolver that targets interface declaration for direct and reverse mappings.
internal class CustomMemberValueDTOResolver
: IMemberValueResolver<IWithNestedEntity, IWithNestedDTO, NestedEntity, NestedDTO>
{ ... } // see sample code attached
internal class CustomMemberValueEntityResolver
: IMemberValueResolver<IWithNestedDTO, IWithNestedEntity, NestedDTO, NestedEntity>
{ ... } // see sample code attached
Mapper.Initialize(cfg =>
{
cfg.CreateMap<NestedEntity, NestedDTO>()
.ReverseMap();
cfg.CreateMap<MasterEntity, MasterDTO>()
.ForMember(e => e.Nested,
expr => expr.ResolveUsing<CustomMemberValueDTOResolver, NestedEntity>(e => e.Nested))
.ReverseMap()
.ForMember(e => e.Nested,
expr => expr.ResolveUsing<CustomMemberValueEntityResolver, NestedDTO>(e => e.Nested));
cfg.CreateMap<DetailEntity, DetailDTO>()
.ForMember(e => e.Nested,
expr => expr.ResolveUsing<CustomMemberValueDTOResolver, NestedEntity>(e => e.Nested))
.ReverseMap()
.ForMember(e => e.Nested,
expr => expr.ResolveUsing<CustomMemberValueEntityResolver, NestedDTO>(e => e.Nested));
});
Mapper.AssertConfigurationIsValid();
The problem is that my resolver for the “ReverseMap” part cannot create a new entity when “DestMember” is null
, because DestMember should NEVER BE NULL, since I’m mapping DTO from an existing entity and (for application logic) this code always is provided with a “non-null relation”.
What I see from test code provided is that a mapping is called from an object with a null relation, object that actually should never exists (or even better: I’m not able to get in the logic of what happens).
I’ve digged also source code but actually I’m unable to see who (and where) creates this “empty” object with null
relation.
I see that is difficult to explain the problem, hope that sample attached can better explain my problem. Thanks for any kind of help.
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Comments: 24 (11 by maintainers)
I’d like to get the 6.1.1 release out a bit sooner as a bugfix release for whatever we broke in 6.1.0 😃
What can I say 😃 Try to simplify things. Start small and build to your final setup. Or try something outside your app just to see what AM does. Of course the execution plan differs, mainly because the types are different. I don’t see anything wrong with what AM does.
In your resolver, make sure you’re calling “context.Mapper.Map”, not
Mapper.Map
. This ensures if you’re using dependency injection it’s using the correct resolvers.