Using Mapster Mapper I feel repeating code that should not be necessary.
public class Workshop
{
public Guid Id {get;set;}
public string? Title {get;set;}
public string? Text {get;set;}
public IList<WorkshopParticipant> WorkshopParticipants {get;set;}
}
public class WorkshopDto
{
public Guid Id {get;set;}
public string? Title {get;set;}
public int Participants {get;set;}
}
public class WorkshopWithTextDto : WorkshopDto
{
public string? Text {get;set;}
}
TypeAdapterConfig<Workshop, WorkshopDto>.NewConfig()
.Map(dest => dest.Participants, src => src.Participants!.Count(x => x.Status == "attended")))
// Why should I have this, when WorkshopWithTextDto is inheriting from WorkshopDto that already have the mapping?
TypeAdapterConfig<Workshop, WorkshopWithTextDto>.NewConfig()
.Map(dest => dest.Participants, src => src.Participants!.Count(x => x.Status == "attended")))
Is there any way I can reuse the mapping, so that I don't have to repeat the participant counting?
From other SO-questions I see that it's possible to use a tuple on the source object, but it doesn't seem to be possible on the destination - or am I wrong?
The participant-counting example is just to describe the problem. Often it's far more complex calculations, that would be nice to only have to maintain one place.
One solution is to have a function that assigns a value to the destination, like:
public static int CountParticipants(IList<WorkshopParticipant> workshopParticipants)
{
return workshopParticipants!.Count(x => x.Status == "attended");
}
TypeAdapterConfig<Workshop, WorkshopDto>.NewConfig()
.Map(dest => dest.Participants, src => CountParticipants(src.WorkshopParticipants!))
TypeAdapterConfig<Workshop, WorkshopWithTextDto>.NewConfig()
.Map(dest => dest.Participants, src => CountParticipants(src.WorkshopParticipants!))
But I would still have to do two TypeAdapterConfigs.
Can this be done "smarter" - more easy to maintain?
See my comment under your question. Also, according to Mapster documentation, you can include derived type to the based type declaration so it copies its settings: