Skip to content

Commit 5a5623b

Browse files
committed
FIx RequiredProperty
1 parent 23a5089 commit 5a5623b

15 files changed

+92
-15
lines changed

src/Mapster.Immutable/ImmutableAdapter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ protected override Expression CreateBlockExpression(Expression source, Expressio
6969
return Expression.Empty();
7070
}
7171

72-
protected override Expression CreateInlineExpression(Expression source, CompileArgument arg)
72+
protected override Expression CreateInlineExpression(Expression source, CompileArgument arg, bool IsRequiredOnly = false)
7373
{
7474
return CreateInstantiationExpression(source, arg);
7575
}

src/Mapster.JsonNet/JsonAdapter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ protected override Expression CreateBlockExpression(Expression source, Expressio
5151
throw new System.NotImplementedException();
5252
}
5353

54-
protected override Expression CreateInlineExpression(Expression source, CompileArgument arg)
54+
protected override Expression CreateInlineExpression(Expression source, CompileArgument arg, bool IsRequiredOnly = false)
5555
{
5656
throw new System.NotImplementedException();
5757
}

src/Mapster.Tests/Mapster.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
<AssemblyOriginatorKeyFile>Mapster.Tests.snk</AssemblyOriginatorKeyFile>
88
<SignAssembly>true</SignAssembly>
99
<PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>
10+
<LangVersion>11.0</LangVersion>
1011
</PropertyGroup>
1112
<ItemGroup>
1213
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />

src/Mapster.Tests/WhenMappingRecordRegression.cs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,25 @@ public void WhenRecordTypeWorksWithUseDestinationValueAndIgnoreNullValues()
422422

423423
}
424424

425+
[TestMethod]
426+
public void RequiredProperty()
427+
{
428+
var source = new Person553 { FirstMidName = "John", LastName = "Dow" };
429+
var destination = new Person554 { ID = 245, FirstMidName = "Mary", LastName = "Dow" };
430+
431+
TypeAdapterConfig<Person553, Person554>.NewConfig()
432+
//.Map(dest => dest.ID, source => 0)
433+
.Ignore(x => x.ID);
434+
435+
var s = source.BuildAdapter().CreateMapToTargetExpression<Person554>();
436+
437+
var result = source.Adapt(destination);
438+
439+
result.ID.ShouldBe(245);
440+
result.FirstMidName.ShouldBe(source.FirstMidName);
441+
result.LastName.ShouldBe(source.LastName);
442+
}
443+
425444
#region NowNotWorking
426445

427446
/// <summary>
@@ -448,6 +467,22 @@ public void CollectionUpdate()
448467

449468

450469
#region TestClasses
470+
471+
public class Person553
472+
{
473+
474+
public string LastName { get; set; }
475+
public string FirstMidName { get; set; }
476+
}
477+
478+
public class Person554
479+
{
480+
public required int ID { get; set; }
481+
public string LastName { get; set; }
482+
public string FirstMidName { get; set; }
483+
}
484+
485+
451486
public class SourceFromTestUseDestValue
452487
{
453488
public int? A { get; set; }

src/Mapster/Adapters/ArrayAdapter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ protected override Expression CreateBlockExpression(Expression source, Expressio
7070
return CreateArraySet(source, destination, arg);
7171
}
7272

73-
protected override Expression CreateInlineExpression(Expression source, CompileArgument arg)
73+
protected override Expression CreateInlineExpression(Expression source, CompileArgument arg, bool IsRequiredOnly = false)
7474
{
7575
if (arg.DestinationType.GetTypeInfo().IsAssignableFrom(source.Type.GetTypeInfo()))
7676
return source;

src/Mapster/Adapters/BaseAdapter.cs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,17 @@ protected Expression CreateBlockExpressionBody(Expression source, Expression? de
221221
vars.Add(src);
222222
transformedSource = src;
223223
}
224-
var set = CreateInstantiationExpression(transformedSource, destination, arg);
224+
225+
Expression? set;
226+
var requiremembers = arg.DestinationType.GetProperties()
227+
.Where(x => x.GetCustomAttributes()
228+
.Any(y => y.GetType() == typeof(System.Runtime.CompilerServices.RequiredMemberAttribute)));
229+
230+
if (requiremembers.Count() != 0)
231+
set = CreateInlineExpression(source, arg, true);
232+
else
233+
set = CreateInstantiationExpression(transformedSource, destination, arg);
234+
225235
if (destination != null && (UseTargetValue || arg.UseDestinationValue) && arg.GetConstructUsing()?.Parameters.Count != 2)
226236
{
227237
if (destination.CanBeNull())
@@ -388,7 +398,8 @@ private static Expression InvokeMapping(
388398
}
389399

390400
protected abstract Expression CreateBlockExpression(Expression source, Expression destination, CompileArgument arg);
391-
protected abstract Expression? CreateInlineExpression(Expression source, CompileArgument arg);
401+
protected abstract Expression? CreateInlineExpression(Expression source, CompileArgument arg, bool IsRequiredOnly = false);
402+
392403

393404
protected Expression CreateInstantiationExpression(Expression source, CompileArgument arg)
394405
{

src/Mapster/Adapters/BaseClassAdapter.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,15 @@ select fn(src, destinationMember, arg))
5454
Destination = (ParameterExpression?)destination,
5555
UseDestinationValue = arg.MapType != MapType.Projection && destinationMember.UseDestinationValue(arg),
5656
};
57+
if(getter == null && destinationMember.Info is PropertyInfo propinfo)
58+
{
59+
if (propinfo.GetCustomAttributes()
60+
.Any(y => y.GetType() == typeof(System.Runtime.CompilerServices.RequiredMemberAttribute)))
61+
{
62+
getter = destinationMember.Type.CreateDefault();
63+
}
64+
}
65+
5766
if (arg.MapType == MapType.MapToTarget && getter == null && arg.DestinationType.IsRecordType())
5867
{
5968
getter = TryRestoreRecordMember(destinationMember, recordRestorMemberModel, destination) ?? getter;
@@ -197,6 +206,17 @@ protected virtual ClassModel GetSetterModel(CompileArgument arg)
197206
};
198207
}
199208

209+
protected virtual ClassModel GetOnlyRequiredPropertySetterModel(CompileArgument arg)
210+
{
211+
return new ClassModel
212+
{
213+
Members = arg.DestinationType.GetFieldsAndProperties(true)
214+
.Where(x => x.GetType() == typeof(PropertyModel))
215+
.Where(y => ((PropertyInfo)y.Info).GetCustomAttributes()
216+
.Any(y => y.GetType() == typeof(System.Runtime.CompilerServices.RequiredMemberAttribute)))
217+
};
218+
}
219+
200220
protected Expression? TryRestoreRecordMember(IMemberModelEx member, ClassModel? restorRecordModel, Expression? destination)
201221
{
202222
if (restorRecordModel != null && destination != null)

src/Mapster/Adapters/ClassAdapter.cs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ private static Expression SetValueByReflection(MemberMapping member, MemberExpre
191191
new[] { member.Destination, memberAsObject });
192192
}
193193

194-
protected override Expression? CreateInlineExpression(Expression source, CompileArgument arg)
194+
protected override Expression? CreateInlineExpression(Expression source, CompileArgument arg, bool IsRequiredOnly = false)
195195
{
196196
//new TDestination {
197197
// Prop1 = convert(src.Prop1),
@@ -202,8 +202,18 @@ private static Expression SetValueByReflection(MemberMapping member, MemberExpre
202202
var memberInit = exp as MemberInitExpression;
203203
var newInstance = memberInit?.NewExpression ?? (NewExpression)exp;
204204
var contructorMembers = newInstance.Arguments.OfType<MemberExpression>().Select(me => me.Member).ToArray();
205-
var classModel = GetSetterModel(arg);
206-
var classConverter = CreateClassConverter(source, classModel, arg);
205+
ClassModel? classModel;
206+
ClassMapping? classConverter;
207+
if (IsRequiredOnly)
208+
{
209+
classModel = GetOnlyRequiredPropertySetterModel(arg);
210+
classConverter = CreateClassConverter(source, classModel, arg, ctorMapping: true);
211+
}
212+
else
213+
{
214+
classModel = GetSetterModel(arg);
215+
classConverter = CreateClassConverter(source, classModel, arg);
216+
}
207217
var members = classConverter.Members;
208218

209219
var lines = new List<MemberBinding>();

src/Mapster/Adapters/CollectionAdapter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ protected override Expression CreateBlockExpression(Expression source, Expressio
115115
return Expression.Block(actions);
116116
}
117117

118-
protected override Expression CreateInlineExpression(Expression source, CompileArgument arg)
118+
protected override Expression CreateInlineExpression(Expression source, CompileArgument arg, bool IsRequiredOnly = false)
119119
{
120120
if (arg.DestinationType.GetTypeInfo().IsAssignableFrom(source.Type.GetTypeInfo()) &&
121121
(arg.Settings.ShallowCopyForSameType == true || arg.MapType == MapType.Projection))

src/Mapster/Adapters/DelegateAdapter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ protected override Expression CreateBlockExpression(Expression source, Expressio
3030
return Expression.Empty();
3131
}
3232

33-
protected override Expression CreateInlineExpression(Expression source, CompileArgument arg)
33+
protected override Expression CreateInlineExpression(Expression source, CompileArgument arg, bool IsRequiredOnly = false)
3434
{
3535
return CreateInstantiationExpression(source, arg);
3636
}

src/Mapster/Adapters/DictionaryAdapter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ private Expression CreateSetFromKvp(Expression kvp, Expression key, Expression d
181181
return destSetFn(destination, key, value);
182182
}
183183

184-
protected override Expression CreateInlineExpression(Expression source, CompileArgument arg)
184+
protected override Expression CreateInlineExpression(Expression source, CompileArgument arg, bool IsRequiredOnly = false)
185185
{
186186
//new TDestination {
187187
// { "Prop1", convert(src.Prop1) },

src/Mapster/Adapters/MultiDimensionalArrayAdapter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ protected override Expression CreateBlockExpression(Expression source, Expressio
9191
return CreateArraySet(source, destination, arg);
9292
}
9393

94-
protected override Expression CreateInlineExpression(Expression source, CompileArgument arg)
94+
protected override Expression CreateInlineExpression(Expression source, CompileArgument arg, bool IsRequiredOnly = false)
9595
{
9696
throw new NotImplementedException();
9797
}

src/Mapster/Adapters/ObjectAdapter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ protected override Expression CreateBlockExpression(Expression source, Expressio
2727
return Expression.Empty();
2828
}
2929

30-
protected override Expression CreateInlineExpression(Expression source, CompileArgument arg)
30+
protected override Expression CreateInlineExpression(Expression source, CompileArgument arg, bool IsRequiredOnly = false)
3131
{
3232
return CreateInstantiationExpression(source, arg);
3333
}

src/Mapster/Adapters/PrimitiveAdapter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ protected override Expression CreateBlockExpression(Expression source, Expressio
9292
throw new NotImplementedException();
9393
}
9494

95-
protected override Expression CreateInlineExpression(Expression source, CompileArgument arg)
95+
protected override Expression CreateInlineExpression(Expression source, CompileArgument arg, bool IsRequiredOnly = false)
9696
{
9797
throw new NotImplementedException();
9898
}

src/Mapster/Adapters/RecordTypeAdapter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ protected override bool CanInline(Expression source, Expression? destination, Co
2727
return false;
2828
}
2929

30-
protected override Expression CreateInlineExpression(Expression source, CompileArgument arg)
30+
protected override Expression CreateInlineExpression(Expression source, CompileArgument arg, bool IsRequiredOnly = false)
3131
{
3232
return base.CreateInstantiationExpression(source, arg);
3333
}

0 commit comments

Comments
 (0)