From 2ac4d752dc493b60816f41d00d53f01594c9eebf Mon Sep 17 00:00:00 2001 From: DocSvartz Date: Sun, 19 Jan 2025 09:38:54 +0500 Subject: [PATCH 1/3] add support using MapWith as param in UseDestinatonValue --- ...WhenUseDestinatonValueMappingRegression.cs | 112 ++++++++++++++++++ src/Mapster/Adapters/BaseAdapter.cs | 15 +++ 2 files changed, 127 insertions(+) create mode 100644 src/Mapster.Tests/WhenUseDestinatonValueMappingRegression.cs diff --git a/src/Mapster.Tests/WhenUseDestinatonValueMappingRegression.cs b/src/Mapster.Tests/WhenUseDestinatonValueMappingRegression.cs new file mode 100644 index 0000000..5dea9da --- /dev/null +++ b/src/Mapster.Tests/WhenUseDestinatonValueMappingRegression.cs @@ -0,0 +1,112 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Shouldly; +using System.Collections.Generic; +using System.Linq; + +namespace Mapster.Tests; + +[TestClass] +public class WhenUseDestinatonValueMappingRegression +{ + [TestClass] + public class WhenUseDestinatonMappingRegression + { + [TestMethod] + public void UseDestinatonValueUsingMapWithasParam() + { + TypeAdapterConfig.GlobalSettings.Default.UseDestinationValue(m => m.SetterModifier == AccessModifier.None && + m.Type.IsGenericType && + m.Type.GetGenericTypeDefinition() == typeof(ICollection<>)); + + TypeAdapterConfig> + .NewConfig() + .MapWith(src => MapThumbnailDetailsData(src).ToList()); + + var channelSrc = new ChannelSource + { + ChannelId = "123", + Thumbnails = new ThumbnailDetailsSource + { + Default = new ThumbnailSource + { + Url = "https://www.youtube.com/default.jpg" + }, + Medium = new ThumbnailSource + { + Url = "https://www.youtube.com/medium.jpg" + }, + High = new ThumbnailSource + { + Url = "https://www.youtube.com/high.jpg" + } + }, + + TempThumbnails = new List() { 1, 2, 3 } + }; + + var script = channelSrc.BuildAdapter() + .CreateMapExpression(); + + var channelDest = channelSrc.Adapt(); + + channelDest.Thumbnails.Count.ShouldBe(3); + channelDest.TempThumbnails.Count.ShouldBe(3); + } + + + #region TestClasses + private static IEnumerable MapThumbnailDetailsData(ThumbnailDetailsSource thumbnailDetails) + { + + yield return MapThumbnail(thumbnailDetails.Default, "Default"); + yield return MapThumbnail(thumbnailDetails.Medium, "Medium"); + yield return MapThumbnail(thumbnailDetails.High, "High"); + } + + private static ThumbnailDestination MapThumbnail( + ThumbnailSource thumbnail, + string thumbnailType) => + new() + { + Type = thumbnailType, + Url = thumbnail.Url.Trim(), + }; + + + + public class ChannelDestination + { + public string ChannelId { get; set; } = default!; + public ICollection Thumbnails { get; } = new List(); + public ICollection TempThumbnails { get; } = new List(); + } + + public class ThumbnailDestination + { + public string Type { get; set; } = default!; + public string Url { get; set; } = default!; + } + + public class ChannelSource + { + public string ChannelId { get; set; } = default!; + public ThumbnailDetailsSource Thumbnails { get; set; } = default!; + public ICollection TempThumbnails { get; set; } = new List(); + + } + + public class ThumbnailDetailsSource + { + public ThumbnailSource? Default { get; set; } + public ThumbnailSource? Medium { get; set; } + public ThumbnailSource? High { get; set; } + } + + public class ThumbnailSource + { + public string Url { get; set; } = default!; + } + + #endregion TestClasses + } +} diff --git a/src/Mapster/Adapters/BaseAdapter.cs b/src/Mapster/Adapters/BaseAdapter.cs index 366f1ee..2fbcf32 100644 --- a/src/Mapster/Adapters/BaseAdapter.cs +++ b/src/Mapster/Adapters/BaseAdapter.cs @@ -495,6 +495,21 @@ internal Expression CreateAdaptExpression(Expression source, Type destinationTyp if (transform != null) exp = transform.TransformFunc(exp.Type).Apply(arg.MapType, exp); } + else + { + if (exp.NodeType == ExpressionType.Call) + { + var argExt = new CompileArgument + { + DestinationType = arg.DestinationType, + SourceType = arg.DestinationType, + MapType = MapType.MapToTarget, + Context = arg.Context, + }; + + return CreateAdaptExpressionCore(exp, destinationType, argExt, mapping, destination); + } + } return exp.To(destinationType); } From 95e43743aa59d8456ccbbd9804fb427af8b18487 Mon Sep 17 00:00:00 2001 From: DocSvartz Date: Sun, 19 Jan 2025 19:47:04 +0500 Subject: [PATCH 2/3] refactoring test --- .../WhenUseDestinatonValueMappingRegression.cs | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/src/Mapster.Tests/WhenUseDestinatonValueMappingRegression.cs b/src/Mapster.Tests/WhenUseDestinatonValueMappingRegression.cs index 5dea9da..4200ada 100644 --- a/src/Mapster.Tests/WhenUseDestinatonValueMappingRegression.cs +++ b/src/Mapster.Tests/WhenUseDestinatonValueMappingRegression.cs @@ -14,10 +14,6 @@ public class WhenUseDestinatonMappingRegression [TestMethod] public void UseDestinatonValueUsingMapWithasParam() { - TypeAdapterConfig.GlobalSettings.Default.UseDestinationValue(m => m.SetterModifier == AccessModifier.None && - m.Type.IsGenericType && - m.Type.GetGenericTypeDefinition() == typeof(ICollection<>)); - TypeAdapterConfig> .NewConfig() .MapWith(src => MapThumbnailDetailsData(src).ToList()); @@ -43,10 +39,7 @@ public void UseDestinatonValueUsingMapWithasParam() TempThumbnails = new List() { 1, 2, 3 } }; - - var script = channelSrc.BuildAdapter() - .CreateMapExpression(); - + var channelDest = channelSrc.Adapt(); channelDest.Thumbnails.Count.ShouldBe(3); @@ -57,7 +50,6 @@ public void UseDestinatonValueUsingMapWithasParam() #region TestClasses private static IEnumerable MapThumbnailDetailsData(ThumbnailDetailsSource thumbnailDetails) { - yield return MapThumbnail(thumbnailDetails.Default, "Default"); yield return MapThumbnail(thumbnailDetails.Medium, "Medium"); yield return MapThumbnail(thumbnailDetails.High, "High"); @@ -73,11 +65,14 @@ private static ThumbnailDestination MapThumbnail( }; - public class ChannelDestination { public string ChannelId { get; set; } = default!; + + [UseDestinationValue] public ICollection Thumbnails { get; } = new List(); + + [UseDestinationValue] public ICollection TempThumbnails { get; } = new List(); } @@ -92,7 +87,6 @@ public class ChannelSource public string ChannelId { get; set; } = default!; public ThumbnailDetailsSource Thumbnails { get; set; } = default!; public ICollection TempThumbnails { get; set; } = new List(); - } public class ThumbnailDetailsSource From b3e2c45518c29cb1ab0f075ac8ce5573c7fd5762 Mon Sep 17 00:00:00 2001 From: DocSvartz Date: Mon, 20 Jan 2025 16:03:42 +0500 Subject: [PATCH 3/3] update algoritm --- src/Mapster/Adapters/BaseAdapter.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Mapster/Adapters/BaseAdapter.cs b/src/Mapster/Adapters/BaseAdapter.cs index 2fbcf32..0c3e4fb 100644 --- a/src/Mapster/Adapters/BaseAdapter.cs +++ b/src/Mapster/Adapters/BaseAdapter.cs @@ -497,7 +497,7 @@ internal Expression CreateAdaptExpression(Expression source, Type destinationTyp } else { - if (exp.NodeType == ExpressionType.Call) + if (exp.NodeType != ExpressionType.Invoke) { var argExt = new CompileArgument { @@ -507,7 +507,7 @@ internal Expression CreateAdaptExpression(Expression source, Type destinationTyp Context = arg.Context, }; - return CreateAdaptExpressionCore(exp, destinationType, argExt, mapping, destination); + return CreateAdaptExpressionCore(exp, destinationType, argExt, mapping, destination).To(destinationType); } }