Skip to content

Commit 5b7fe51

Browse files
committed
feat: #938 - Add DirectAssignmentForSameType setting parametr
1 parent a0cd3c1 commit 5b7fe51

5 files changed

Lines changed: 78 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: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -495,10 +495,19 @@ 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+
505+
if(_source.Type == destinationType && notUsingDestinationValue
506+
&& arg.IsDirectAssignmentForSameTypeEnable(rule, tuple) && arg.IsNotCustomConverterFactory(rule))
507+
return _source.To(destinationType);
508+
509+
var exp = _source.Type == destinationType && arg.Settings.ShallowCopyForSameType == true && notUsingDestinationValue
510+
&& rule == null
502511
? _source
503512
: CreateAdaptExpressionCore(_source, destinationType, arg, mapping, destination);
504513

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: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,5 +466,33 @@ 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 IsDirectAssignmentForSameTypeEnable(this CompileArgument arg, TypeAdapterRule? rule, TypeTuple tuple)
471+
{
472+
473+
if (rule != null)
474+
{
475+
var contexSettings = arg.Context.Config.Rules.Where(x => x.Settings.SourceType == tuple.Source && x.Settings.DestinationType == tuple.Destination).Select(x => x.Settings).FirstOrDefault();
476+
return (rule?.Settings.DirectAssignmentForSameType).GetValueOrDefault() || (contexSettings?.DirectAssignmentForSameType).GetValueOrDefault();
477+
}
478+
479+
if (arg.Context.Config.Default.Settings.DirectAssignmentForSameType.GetValueOrDefault())
480+
return true;
481+
482+
return false;
483+
}
484+
485+
public static bool IsNotCustomConverterFactory(this CompileArgument arg, TypeAdapterRule? rule)
486+
{
487+
if(rule != null)
488+
{
489+
if(arg.MapType == MapType.Map && rule.Settings.ConverterFactory != null)
490+
return false;
491+
if (arg.MapType == MapType.MapToTarget && rule.Settings.ConverterToTargetFactory != null)
492+
return false;
493+
}
494+
495+
return true;
496+
}
469497
}
470498
}

0 commit comments

Comments
 (0)