Multiple sources - Mapping required for every member
Issue https://github.com/MapsterMapper/Mapster/issues/180 shows how to solve the need for multiple sources using tuples, and that it is implemented in Mapster 5.0.
However, using multiple sources as stated in the docs introduces a heavy constraint, which is to map every member manually. In the following code, dto.CommonValue is null if not explicitly mapped in the config.
record PocoA(string SpecificValue);
record PocoB(int CommonValue);
record Dto(int CommonValue, int SumValue);
//...
TypeAdapterConfig.GlobalSettings.NewConfig<(PocoA, PocoB), Dto>()
.Map(dto => dto.SumValue, pocoTuple => pocoTuple.Item1.SpecificValue + pocoTuple.Item2.CommonValue);
// ...
var dto = mapper.Map<(PocoA, PocoB), Dto>(pocoA, pocoB); // dto.CommonValue is null
Is there a solution to this? It breaks the workflow in some large objects. If a single parameter needs an additional source, every single member needs to be mapped manually.
Hi @ChristopheLionet, could you post a complete code sample please?
I am also having this issue, though maybe I am not setting up the config correctly?
Code can be run here
using System;
using Mapster;
public class Program
{
public static void Main()
{
TypeAdapterConfig<(Source1, Source2), Dest>.NewConfig()
.Map(dest => dest, src => src.Item1)
.Map(dest => dest, src => src.Item2);
var src1 = new Source1{MyInt = 1};
var src2 = new Source2{MyString = "Hello"};
//Doesnt work
var destTuple = Tuple.Create(src1, src2).Adapt<Dest>();
//Works
var destSrc1 = src1.Adapt<Dest>();
var destSrc2 = src2.Adapt<Dest>();
Console.WriteLine($"Tuple Mapping {destTuple.MyInt} {destTuple.MyString}");
Console.WriteLine($"Regular Mapping src1 {destSrc1.MyInt} {destSrc1.MyString}");
Console.WriteLine($"Regular Mapping src2 {destSrc2.MyInt} {destSrc2.MyString}");
}
}
internal sealed class Source1 {
public int MyInt {get; init;}
}
public class Source2 {
public string MyString {get; init;}
}
public record Dest {
public int MyInt {get; init;}
public string MyString {get; init;}
}
Hello @andrerav , @jackfrosty908
(Source1, Source2) is ValueTuple, not a Tuple
But Adapt in Record in this form is not work with RecordType fix
public record Dest {
public int MyInt {get; init;}
public string MyString {get; init;}
}
/// <summary>
/// https://github.com/MapsterMapper/Mapster/issues/501
/// </summary>
[TestMethod]
public void MultiplyTuple()
{
TypeAdapterConfig<(Source501, Dest501), DestRecord501>.NewConfig()
.Map(dest => dest, src => src.Item1)
.Map(dest => dest, src => src.Item2);
var src1 = new Source501 { MyInt = 1 };
var src2 = new Dest501 { MyString = "Hello" };
//work
var destTuple = ValueTuple.Create(src1, src2).Adapt<DestRecord501>();
//Works
var destSrc1 = src1.Adapt<DestRecord501>();
var destSrc2 = src2.Adapt<DestRecord501>();
}
internal sealed class Source501
{
public int MyInt { get; init; }
}
public class Dest501
{
public string MyString { get; init; }
}
public record DestRecord501 (int MyInt, string MyString);
@andrerav i Fix this bug in RecordAdapter. It will be ready along with the attribute for the legacy record description )
That's awesome @DocSvartz! Please mention the issue number in the PR and I'll make sure that it's closed after merging :)