diff --git a/src/Mapster.Tests/WhenMappingRecordRegression.cs b/src/Mapster.Tests/WhenMappingRecordRegression.cs
index 4a065274..94518641 100644
--- a/src/Mapster.Tests/WhenMappingRecordRegression.cs
+++ b/src/Mapster.Tests/WhenMappingRecordRegression.cs
@@ -2,6 +2,7 @@
using Shouldly;
using System;
using System.Collections.Generic;
+using System.Text.Json;
using static Mapster.Tests.WhenExplicitMappingRequired;
using static Mapster.Tests.WhenMappingDerived;
@@ -522,6 +523,22 @@ public void ClassCtorActivateDefaultValue()
});
}
+ ///
+ /// https://github.com/MapsterMapper/Mapster/issues/911
+ ///
+ [TestMethod]
+ public void NotSelfCreationTypeMappingToSelfWithOutError()
+ {
+ var src = new Uri("https://www.google.com/");
+ var srcJ = JsonDocument.Parse("{\"key\": \"value\"}");
+
+ var result = src.Adapt();
+ var resultJ = srcJ.Adapt();
+
+ result.ToString().ShouldBe("https://www.google.com/");
+ resultJ.RootElement.GetProperty("key").ToString().ShouldBe("value");
+ }
+
#region NowNotWorking
///
diff --git a/src/Mapster/Adapters/ClassAdapter.cs b/src/Mapster/Adapters/ClassAdapter.cs
index a17b079a..03a2eb6b 100644
--- a/src/Mapster/Adapters/ClassAdapter.cs
+++ b/src/Mapster/Adapters/ClassAdapter.cs
@@ -16,7 +16,7 @@ namespace Mapster.Adapters
///
internal class ClassAdapter : BaseClassAdapter
{
- protected override int Score => -150;
+ protected override int Score => -200;
protected override bool CanMap(PreCompileArgument arg)
{
diff --git a/src/Mapster/Adapters/NotSelfCreationAdapter.cs b/src/Mapster/Adapters/NotSelfCreationAdapter.cs
new file mode 100644
index 00000000..7079ec86
--- /dev/null
+++ b/src/Mapster/Adapters/NotSelfCreationAdapter.cs
@@ -0,0 +1,16 @@
+namespace Mapster.Adapters
+{
+ ///
+ /// Immitation behavior in 7.4.0 for Types that cannot be instantiated from itselves
+ /// Example: Uri, JsonDocument
+ ///
+ internal class NotSelfCreationAdapter : PrimitiveAdapter
+ {
+ protected override int Score => -150;
+
+ protected override bool CanMap(PreCompileArgument arg)
+ {
+ return !arg.ExplicitMapping && arg.SourceType == arg.DestinationType && arg.DestinationType.IsNotSelfCreation();
+ }
+ }
+}
diff --git a/src/Mapster/Adapters/PrimitiveAdapter.cs b/src/Mapster/Adapters/PrimitiveAdapter.cs
index c2d411db..622f32b1 100644
--- a/src/Mapster/Adapters/PrimitiveAdapter.cs
+++ b/src/Mapster/Adapters/PrimitiveAdapter.cs
@@ -9,7 +9,7 @@ namespace Mapster.Adapters
{
internal class PrimitiveAdapter : BaseAdapter
{
- protected override int Score => -200; //must do last
+ protected override int Score => -210; //must do last
protected override bool CanMap(PreCompileArgument arg)
{
diff --git a/src/Mapster/TypeAdapterConfig.cs b/src/Mapster/TypeAdapterConfig.cs
index 1e6abade..34f22495 100644
--- a/src/Mapster/TypeAdapterConfig.cs
+++ b/src/Mapster/TypeAdapterConfig.cs
@@ -20,8 +20,9 @@ private static List CreateRuleTemplate()
{
return new List
{
- new PrimitiveAdapter().CreateRule(), //-200
- new ClassAdapter().CreateRule(), //-150
+ new PrimitiveAdapter().CreateRule(), //-210
+ new ClassAdapter().CreateRule(), //-200
+ new NotSelfCreationAdapter().CreateRule(), //-150
new RecordTypeAdapter().CreateRule(), //-149
new ReadOnlyInterfaceAdapter().CreateRule(), // -148
new CollectionAdapter().CreateRule(), //-125
diff --git a/src/Mapster/Utils/ReflectionUtils.cs b/src/Mapster/Utils/ReflectionUtils.cs
index 505166eb..a010984a 100644
--- a/src/Mapster/Utils/ReflectionUtils.cs
+++ b/src/Mapster/Utils/ReflectionUtils.cs
@@ -453,5 +453,18 @@ public static bool IsMapsterImmutable(this Type type)
{
return type.IsMapsterPrimitive() || type.IsRecordType();
}
+
+ public static bool IsNotSelfCreation(this Type type)
+ {
+ if (type.IsMapsterPrimitive())
+ return false;
+ if(type.IsCollectionCompatible())
+ return false;
+
+ if (type == typeof(Type) || type.BaseType == typeof(MulticastDelegate))
+ return true;
+
+ return type.GetFieldsAndProperties().Any(it => (it.SetterModifier & (AccessModifier.Public | AccessModifier.NonPublic)) == 0);
+ }
}
}