riok / mapperly

A .NET source generator for generating object mappings. No runtime reflection.
https://mapperly.riok.app
Apache License 2.0
2.58k stars 140 forks source link

`[MapProperty]` on a nested target prevents the root member being resolved from the source. #642

Open TimothyMakkison opened 1 year ago

TimothyMakkison commented 1 year ago

Is your feature request related to a problem? Please describe. Using MapProperty to assign a nested value will prevent the root member being auto resolved from the source.

[Mapper]
public static partial class Mapper
{
    [MapProperty("NestedValue", "Nested.Value")]
    public static partial B Map(A source);
}

public class A { public C Nested { get; } public string NestedValue { get; } }
public class B { public C Nested { get; set; } }
public class C { public string Value { get; set; } }

// here target.Nested is not assigned source.Nested
// removing [MapProperty] fixes this
var target = new global::Riok.Mapperly.Sample.B();
target.Nested.Value = source.NestedValue;
return target;

Describe the solution you'd like ObjectMemberMappingBodyBuilder.BuildMappingBody should try to resolve the member if its configs don't map to the target.

I'm not sure how error handling should occur. i.e. If a specified root assignment is invalid, should a resolution be attempted?

latonz commented 1 year ago

This is expected with the current implementation. The current implementation marks all target properties as mapped, which are part of a target property mapping path. Not sure if we should change that.

TimothyMakkison commented 1 year ago

IMO this is pretty confusing. You might have a functioning mapping, but by adjusting a child it stops working. Do automapper/mapster do this?

latonz commented 1 year ago

On a second thought we should probably improve this and map such members unless they are explicitly ignored.

TimothyMakkison commented 1 year ago

👍 think I have the fix already made, see if I can find it