Skip to content

Commit 9bbb178

Browse files
authored
chore: Merge pull request #941 from DocSvartz/feat-938
feat: #938 - Add DirectAssignmentForSameType()
2 parents 1f6d3e7 + 290417f commit 9bbb178

6 files changed

Lines changed: 71 additions & 4 deletions

File tree

src/Mapster.Tests/WhenConfiguringMapping.cs

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,9 +142,9 @@ public void NewInstanceConfigurationTest()
142142
obj.Name = "Tim";
143143
obj.Child = new TestNewInstanceF() { Name = "Kıvanç" };
144144

145-
TypeAdapterConfig<TestNewInstanceD, TestNewInstanceE>
145+
TypeAdapterConfig<TestNewInstanceD, TestNewInstanceE>
146146
.NewConfig()
147-
.ShallowCopyForSameType(true);
147+
.ShallowCopyForSameType(true);
148148

149149
var newObj2 = TypeAdapter.Adapt<TestNewInstanceD, TestNewInstanceE>(obj);
150150

@@ -156,6 +156,28 @@ public void NewInstanceConfigurationTest()
156156
Assert.IsTrue(newObj2.Child.Name == "Antalya");
157157
}
158158

159+
[TestMethod]
160+
public void WhenDirectAssignmentForSameTypeConfigurate()
161+
{
162+
TestNewInstanceD obj = new TestNewInstanceD();
163+
obj.Name = "Tim";
164+
obj.Child = new TestNewInstanceF() { Name = "Kıvanç" };
165+
166+
var config = new TypeAdapterConfig();
167+
config.NewConfig<TestNewInstanceF, TestNewInstanceF>()
168+
.DirectAssignmentForSameType(true);
169+
170+
var newObj2 = TypeAdapter.Adapt<TestNewInstanceD, TestNewInstanceE>(obj, config);
171+
172+
Assert.IsTrue(newObj2.Name == "Tim");
173+
Assert.IsTrue(obj.Child.Name == newObj2.Child.Name);
174+
175+
obj.Child.Name = "Antalya";
176+
177+
Assert.IsTrue(newObj2.Child.Name == "Antalya");
178+
}
179+
180+
159181
#region Data
160182

161183
private Source _source;

src/Mapster/Adapters/BaseAdapter.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -495,10 +495,14 @@ internal Expression CreateAdaptExpression(Expression source, Type destinationTyp
495495
if (_source.Type == destinationType && arg.MapType == MapType.Projection)
496496
return _source;
497497

498+
TypeAdapterRule? rule;
499+
var tuple = new TypeTuple(_source.Type, destinationType);
500+
arg.Context.Config.RuleMap.TryGetValue(tuple, out rule);
501+
498502
//adapt(_source);
499503
var notUsingDestinationValue = mapping is not { UseDestinationValue: true };
500-
var exp = _source.Type == destinationType && arg.Settings.ShallowCopyForSameType == true && notUsingDestinationValue &&
501-
!arg.Context.Config.HasRuleFor(_source.Type, destinationType)
504+
var exp = _source.Type == destinationType && arg.Settings.ShallowCopyForSameType == true && notUsingDestinationValue
505+
&& rule == null
502506
? _source
503507
: CreateAdaptExpressionCore(_source, destinationType, arg, mapping, destination);
504508

src/Mapster/Adapters/ClassAdapter.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,5 +291,18 @@ private static Expression SetValueByReflection(MemberMapping member, MemberExpre
291291

292292
return Expression.MemberInit(newInstance, lines);
293293
}
294+
295+
protected override Expression CreateExpressionBody(Expression source, Expression? destination, CompileArgument arg)
296+
{
297+
TypeAdapterRule? rule;
298+
var tuple = new TypeTuple(source.Type, arg.DestinationType);
299+
arg.Context.Config.RuleMap.TryGetValue(tuple, out rule);
300+
301+
if (source.Type == arg.DestinationType && !arg.UseDestinationValue
302+
&& arg.Settings.DirectAssignmentForSameType.GetValueOrDefault() && arg.IsNotCustomConverterFactory(rule))
303+
return source;
304+
305+
return base.CreateExpressionBody(source, destination, arg);
306+
}
294307
}
295308
}

src/Mapster/TypeAdapterSetter.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,14 @@ public static TSetter ShallowCopyForSameType<TSetter>(this TSetter setter, bool
108108
return setter;
109109
}
110110

111+
public static TSetter DirectAssignmentForSameType<TSetter>(this TSetter setter, bool value) where TSetter : TypeAdapterSetter
112+
{
113+
setter.CheckCompiled();
114+
115+
setter.Settings.DirectAssignmentForSameType = value;
116+
return setter;
117+
}
118+
111119
public static TSetter EnumMappingStrategy<TSetter>(this TSetter setter, EnumMappingStrategy strategy) where TSetter : TypeAdapterSetter
112120
{
113121
setter.CheckCompiled();

src/Mapster/TypeAdapterSettings.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,18 @@ public bool? PreserveReference
3939
get => Get(nameof(PreserveReference));
4040
set => Set(nameof(PreserveReference), value);
4141
}
42+
public bool? DirectAssignmentForSameType
43+
{
44+
get => Get(nameof(DirectAssignmentForSameType));
45+
set => Set(nameof(DirectAssignmentForSameType), value);
46+
}
47+
4248
public bool? ShallowCopyForSameType
4349
{
4450
get => Get(nameof(ShallowCopyForSameType));
4551
set => Set(nameof(ShallowCopyForSameType), value);
4652
}
53+
4754
public bool? IgnoreNullValues
4855
{
4956
get => Get(nameof(IgnoreNullValues));

src/Mapster/Utils/ReflectionUtils.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,5 +466,18 @@ public static bool IsNotSelfCreation(this Type type)
466466

467467
return type.GetFieldsAndProperties().All(it => (it.SetterModifier & (AccessModifier.Public | AccessModifier.NonPublic)) == 0);
468468
}
469+
470+
public static bool IsNotCustomConverterFactory(this CompileArgument arg, TypeAdapterRule? rule)
471+
{
472+
if(rule != null)
473+
{
474+
if(arg.MapType == MapType.Map && rule.Settings.ConverterFactory != null)
475+
return false;
476+
if (arg.MapType == MapType.MapToTarget && rule.Settings.ConverterToTargetFactory != null)
477+
return false;
478+
}
479+
480+
return true;
481+
}
469482
}
470483
}

0 commit comments

Comments
 (0)