diff --git a/src/Mapster.Tests/WhenPerTypeShallowCopyOverride.cs b/src/Mapster.Tests/WhenPerTypeShallowCopyOverride.cs
new file mode 100644
index 00000000..695c2796
--- /dev/null
+++ b/src/Mapster.Tests/WhenPerTypeShallowCopyOverride.cs
@@ -0,0 +1,108 @@
+using Mapster.Models;
+using MapsterMapper;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Shouldly;
+
+namespace Mapster.Tests
+{
+ ///
+ /// https://github.com/MapsterMapper/Mapster/issues/938
+ ///
+ [TestClass]
+ public class WhenPerTypeShallowCopyOverride
+ {
+ [TestMethod]
+ public void GlobalShallowCopy_WithPerTypeDeepCopy_ShouldRestoreViaMapToTarget()
+ {
+ var cfg = new TypeAdapterConfig();
+ cfg.RequireExplicitMapping = true;
+ cfg.Default.ShallowCopyForSameType(true);
+ cfg.Default.AvoidInlineMapping(true);
+
+ cfg.NewConfig();
+ cfg.NewConfig();
+
+ cfg.NewConfig()
+ .ShallowCopyForSameType(false);
+
+ cfg.GetMergedSettings(new TypeTuple(typeof(MyFailStuff), typeof(MyFailStuff)), MapType.Map)
+ .ShallowCopyForSameType.ShouldBe(false);
+
+ cfg.Compile();
+
+ var mapper = new Mapper(cfg);
+
+ var dynamicStuff = new MyFailStuff();
+ dynamicStuff.Item1 = new RandomObject1();
+ dynamicStuff.Item1.SampleName = "SN1";
+ dynamicStuff.Item2 = new RandomObject2();
+ dynamicStuff.Item2.SampleNumber = 2;
+
+ var originalStuff = mapper.Map(dynamicStuff);
+
+ dynamicStuff.Item1.SampleName = "SN1CHANGED";
+ dynamicStuff.Item2.SampleNumber = 3;
+
+ mapper.Map(originalStuff, dynamicStuff);
+
+ dynamicStuff.Item1.SampleName.ShouldBe("SN1");
+ dynamicStuff.Item2.SampleNumber.ShouldBe(2);
+ ReferenceEquals(dynamicStuff.Item1, originalStuff.Item1).ShouldBeFalse();
+ ReferenceEquals(dynamicStuff.Item2, originalStuff.Item2).ShouldBeFalse();
+ }
+
+ [TestMethod]
+ public void ParentDeepCopyOverride_ShouldNotDisableImplicitNestedShallowCopyForSameType()
+ {
+ var cfg = new TypeAdapterConfig();
+ cfg.Default.ShallowCopyForSameType(true);
+ cfg.NewConfig()
+ .ShallowCopyForSameType(false);
+
+ cfg.Compile();
+
+ var src = new Container { Child = new NestedChild { Value = 1 } };
+ var dest = src.Adapt(cfg);
+
+ ReferenceEquals(src.Child, dest.Child).ShouldBeTrue();
+ }
+
+ public class Container
+ {
+ public NestedChild? Child { get; set; }
+ }
+
+ public class NestedChild
+ {
+ public int Value { get; set; }
+ }
+
+ public class MyFailStuff
+ {
+ public MyFailStuff()
+ {
+ CreateEmptyEntities();
+ }
+
+ public void CreateEmptyEntities()
+ {
+ Item1 ??= new RandomObject1();
+ Item2 ??= new RandomObject2();
+ }
+
+ public RandomObject1? Item1 { get; set; }
+
+ public RandomObject2? Item2 { get; set; }
+ }
+
+ public class RandomObject1
+ {
+ public string? SampleName { get; set; }
+ }
+
+ public class RandomObject2
+ {
+ public int SampleNumber { get; set; }
+ }
+ }
+}
diff --git a/src/Mapster/Adapters/BaseAdapter.cs b/src/Mapster/Adapters/BaseAdapter.cs
index b31a0dbe..41c43e28 100644
--- a/src/Mapster/Adapters/BaseAdapter.cs
+++ b/src/Mapster/Adapters/BaseAdapter.cs
@@ -503,7 +503,16 @@ internal Expression CreateAdaptExpression(Expression source, Type destinationTyp
var notUsingDestinationValue = mapping is not { UseDestinationValue: true };
Expression exp;
- if (_source.Type == destinationType && arg.Settings.ShallowCopyForSameType == true
+ var shallowCopySettings = arg.Settings;
+ if (_source.Type == destinationType)
+ {
+ if (arg.Context.Config.RuleMap.ContainsKey(tuple))
+ shallowCopySettings = arg.Context.Config.GetMergedSettings(tuple, arg.MapType);
+ else if (arg.Settings.ShallowCopyForSameType != true)
+ shallowCopySettings = arg.Context.Config.GetMergedSettings(tuple, arg.MapType);
+ }
+
+ if (_source.Type == destinationType && shallowCopySettings.ShallowCopyForSameType == true
&& notUsingDestinationValue && rule == null)
exp = _source;
else if (source is ConditionalExpression cond && mapping != null)