Search code examples
c#mapster

How to merge sub object?


I want to copy an object tree into another using Mapster, but I can't find how to make Mapster stop creating new instances of my sub objects. I want to merge the whole tree, any idea ? Here is a simplified example:

// These are my source objects
public class EditDeliberationCommand : IRequest<Guid>
{ 
    public Guid Id { get; set; }
    public GlobalInformationDto GlobalInformation { get; set; }
}

public class GlobalInformationDto
{ 
    public AudienceType? AudienceType { get; set; }
}

// These are my destination objects
public class Deliberation : AgendaItem
{ 
}

public abstract class AgendaItem : Entity
{ 
    public GlobalInformation GlobalInformation { get; set; } 
}

public class GlobalInformation : ValueObject
{ 
    public AudienceType? AudienceType { get; set; }
    Public AudienceType? ExpectedAudienceType { get; set; }
}

The goal here is to merge EditDeliberationCommand into Deliberation, and the GlobalInformationDto should be merged into the GlobalInformation value object. But whatever the configuration I tried, Mapster always creates a new GlobalInformation.

The example is very simplified here, I have many other simple properties that are copied from EditDeliberationCommand to Deliberation just fine.

How can I configure Mapster to do what I want ?

EDIT Here is a minimal example as requested by @guru-stron: https://github.com/daaa57150/MapsterTests

By building it I just found out how to correct the behavior of Mapster: the sub object needs a public empty constructor. I have no idea why and would happily get explanations.


Solution

  • The problem seems to be a combination of factors, main one being the presence of ctor with parameters:

    public Child(int property1, int property2)
    {
        Debug.WriteLine($"new Child({property1}, {property2})");
        Property1 = property1;
        Property2 = property2;
    }
    

    If you remove it or make it private (or make public the parameterless one) then everything will work as expected.

    I was not able to override the behavior via config

    See also:

    UPD

    Upgrading to latest pre-release version (7.4.2-pre02) seems to fix the problem (though I needed to upgrade .NET also)