Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions src/Mapster.Tests/WhenUseDestinatonValueMappingRegression.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,39 @@ public void UseDestinatonValueUsingMapWithasParam()
channelDest.TempThumbnails.Count.ShouldBe(3);
}

[TestMethod]
public void UseDestinatonValueFromSimpleConfigMethod()
{
var config = new TypeAdapterConfig();
config.NewConfig<SimplySourceContractingParty, SimplyDestinationContractingParty>()
.UseDestinationValue(dest => dest.Company);

var source = new SimplySourceContractingParty() { Company = new() { CompanyName = "Mapster" } };

var notUseDestinatonValue = source.Adapt<SimplyDestinationContractingParty>();
var UseDestinatonValue = source.Adapt<SimplyDestinationContractingParty>(config);

notUseDestinatonValue.Company.CompanyName.ShouldBeNullOrEmpty();
UseDestinatonValue.Company.CompanyName.ShouldBe(source.Company.CompanyName);
}

#region TestClasses

public class SimplySourceContractingParty
{
public SimplyContractingParty Company { get; set; }
}

public class SimplyDestinationContractingParty
{
public SimplyContractingParty Company { get; } = new();
}

public class SimplyContractingParty
{
public string CompanyName { get; set; }
}

private static IEnumerable<ThumbnailDestination> MapThumbnailDetailsData(ThumbnailDetailsSource thumbnailDetails)
{
yield return MapThumbnail(thumbnailDetails.Default, "Default");
Expand Down
12 changes: 11 additions & 1 deletion src/Mapster/Adapters/BaseClassAdapter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

#region Build the Adapter Model

protected ClassMapping CreateClassConverter(Expression source, ClassModel classModel, CompileArgument arg, Expression? destination = null, bool ctorMapping = false, ClassModel recordRestorMemberModel = null)

Check warning on line 18 in src/Mapster/Adapters/BaseClassAdapter.cs

View workflow job for this annotation

GitHub Actions / build

Cannot convert null literal to non-nullable reference type.
{
var destinationMembers = classModel.Members;
var unmappedDestinationMembers = new List<string>();
Expand Down Expand Up @@ -111,7 +111,7 @@
NextIgnore = nextIgnore,
Source = (ParameterExpression)source,
Destination = (ParameterExpression?)destination,
UseDestinationValue = arg.MapType != MapType.Projection && destinationMember.UseDestinationValue(arg),
UseDestinationValue = IsCanUsingDestinationValue(arg, destinationMember),
};
if(getter == null && !arg.DestinationType.IsRecordType()
&& destinationMember.Info is PropertyInfo propinfo)
Expand Down Expand Up @@ -189,6 +189,16 @@
};
}

protected static bool IsCanUsingDestinationValue(CompileArgument arg, IMemberModelEx destinationMember)
{
if (arg.MapType == MapType.Projection)
return false;
if (destinationMember.UseDestinationValue(arg) || arg.Settings.UseDestinationMembers.Contains(destinationMember.Name))
return true;

return false;
}

protected static bool ProcessIgnores(
CompileArgument arg,
IMemberModel destinationMember,
Expand All @@ -202,7 +212,7 @@
&& ignore.Condition == null;
}

protected Expression CreateInstantiationExpression(Expression source, ClassMapping classConverter, CompileArgument arg, Expression? destination, ClassModel recordRestorParamModel = null)

Check warning on line 215 in src/Mapster/Adapters/BaseClassAdapter.cs

View workflow job for this annotation

GitHub Actions / build

Cannot convert null literal to non-nullable reference type.
{
var members = classConverter.Members;

Expand Down
20 changes: 20 additions & 0 deletions src/Mapster/TypeAdapterSetter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -510,6 +510,26 @@ public TypeAdapterSetter<TDestination> AfterMappingInline(Expression<Action<TDes
Settings.AfterMappingFactories.Add(arg => lambda);
return this;
}

public TypeAdapterSetter<TDestination> UseDestinationValue<TDestinationMember>(Expression<Func<TDestination, TDestinationMember>> destinationMember)
{
this.CheckCompiled();
var memberName = destinationMember.GetMemberPath()!;

if (memberName != null)
Settings.UseDestinationMembers.Add(memberName);

return this;
}

public TypeAdapterSetter UseDestinationValue(string destinationMemberName)
{
this.CheckCompiled();
Settings.UseDestinationMembers.Add(destinationMemberName);

return this;
}

}

[System.Diagnostics.CodeAnalysis.SuppressMessage("Minor Code Smell", "S4136:Method overloads should be grouped together", Justification = "<Pending>")]
Expand Down
5 changes: 5 additions & 0 deletions src/Mapster/TypeAdapterSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,11 @@ public Action<TypeAdapterConfig>? Fork
set => Set(nameof(Fork), value);
}

public List<string> UseDestinationMembers
{
get => Get(nameof(UseDestinationMembers), () => new List<string>());
}

internal bool Compiled { get; set; }

public TypeAdapterSettings Clone()
Expand Down
Loading