MapsterMapper / Mapster

A fast, fun and stimulating object to object Mapper
MIT License
4.3k stars 328 forks source link

Mapster.Tool incorrect codegen map to existing object #510

Closed heggi closed 1 year ago

heggi commented 1 year ago

Empty console project for .Net 6.0 with nullable enabled

public struct Source
{
    public string Name { get; set; }
}

public struct Dest
{
    public string Name { get; set; }
}

[Mapper]
public interface ITestMapping
{
    Dest AdaptTo(Source source, Dest dest);
}

Got next generated code:

public partial class TestMapping : ITestMapping
{
    public Dest AdaptTo(Source p1, Dest p2)
    {
        Dest result = new Dest();

        result.Name = p1.Name;
        return result;

    }
}

Parameter p2 doesn't used. But expected next code

public partial class TestMapping : ITestMapping
{
    public Dest AdaptTo(Source p1, Dest p2)
    {
        p2.Name = p1.Name;
        return p2;
    }
}
heggi commented 1 year ago

Same trouble with basic mapper

public struct Source
{
    public string Name { get; set; }
}
public struct Dest
{
    public string Name { get; set; }

    public string Ignore { get; set; }
}

TypeAdapterConfig<Source, Dest>
    .NewConfig()
    .Ignore(s => s.Ignore);

var source = new Source
{
    Name = "test",
};
var dest = new Dest
{
    Ignore = "ignore",
};

dest = source.Adapt(dest);

Console.WriteLine($"{dest.Name} {dest.Ignore}");

Got result test, but expected test ignore

If I change Dest from struct to class, mapper work right.

andrerav commented 1 year ago

Probably the same issue as #450. This should definitely work. Which version of Mapster are you using?

andrerav commented 1 year ago

After some quick testing, I found the following:

andrerav commented 1 year ago

Here's the 4.1.0 release: https://github.com/MapsterMapper/Mapster/releases/tag/4.1.0 "Fixed mapping to existing struct" is mentioned in the release notes.

andrerav commented 1 year ago

The crash introduced in v3.0.0 was reported in #195, and then this commit was added to fix the issue: https://github.com/MapsterMapper/Mapster/commit/2e3b235f5d83b4347da6515aca68149135b47261

So that looks like a good place to start hacking :)

heggi commented 1 year ago

Which version of Mapster are you using?

Latest release version 7.3.0

andrerav commented 1 year ago

@heggi Alright, thank you. This bug has existed since 2017 when it was broken in v3.0.0. There are only two unit tests related to this (in the WhenMappingStruct test class), and neither of them tests mapping of actual structs, only mapping of class properties that are structs.

andrerav commented 1 year ago

@heggi I believe I have found a fix for this. I haven't tested this with Mapster.Tool yet, but I think the fix should carry over there as well. When I have verified the fix in Mapster.Tool I'll push a prerelease package that you can test.

andrerav commented 1 year ago

@heggi I've verified that this fixes the issue for both basic mapping and code generation. Please try version 8.4.0-pre05 and let me know how it goes:

dotnet tool install --global Mapster.Tool --version 8.4.0-pre05

heggi commented 1 year ago

It works very well in my case

andrerav commented 1 year ago

Great, thank you! This fix will be included in Mapster.Tool 8.4.0 and Mapster 7.4.0 which should be released in a few weeks at the latest.