Skip to content

Commit

Permalink
Merge pull request #634 from DocSvartz/NewRecordDetecton
Browse files Browse the repository at this point in the history
New Record detection - Adapt To Class not create new instance
  • Loading branch information
andrerav authored Oct 15, 2023
2 parents 2f7034d + f678d12 commit 09a0e92
Show file tree
Hide file tree
Showing 6 changed files with 549 additions and 20 deletions.
47 changes: 47 additions & 0 deletions src/Mapster.Core/Utils/RecordTypeIdentityHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
using System;
using System.Linq;
using System.Reflection;

namespace Mapster.Utils
{
/// <summary>
/// CheckTools from Distinctive features of RecordType according to specification:
/// https://github.com/dotnet/docs/blob/main/docs/csharp/language-reference/builtin-types/record.md
/// </summary>
public static class RecordTypeIdentityHelper
{
private static bool IsRecordСonstructor(Type type)
{
var ctors = type.GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public).ToList();

if (ctors.Count < 2)
return false;

var isRecordTypeCtor = type.GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic)
.Where(x => x.IsFamily == true || (type.IsSealed && x.IsPrivate == true)) // add target from Sealed record
.Any(x => x.GetParameters()
.Any(y => y.ParameterType == type));

if (isRecordTypeCtor)
return true;

return false;
}

private static bool IsIncludedRecordCloneMethod(Type type)
{
if( type.GetMethod("<Clone>$")?.MethodImplementationFlags.HasFlag(MethodImplAttributes.IL) == true)
return true;

return false;
}

public static bool IsRecordType(Type type)
{
if (IsRecordСonstructor(type) && IsIncludedRecordCloneMethod(type))
return true;

return false;
}
}
}
3 changes: 2 additions & 1 deletion src/Mapster.Tests/WhenIgnoringConditionally.cs
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ public void IgnoreIf_Can_Be_Combined()
public void IgnoreIf_Apply_To_RecordType()
{
TypeAdapterConfig<SimplePoco, SimpleRecord>.NewConfig()
.EnableNonPublicMembers(true) // add or
.IgnoreIf((src, dest) => src.Name == "TestName", dest => dest.Name)
.Compile();

Expand Down Expand Up @@ -187,7 +188,7 @@ public class SimpleDto
public string Name { get; set; }
}

public class SimpleRecord
public class SimpleRecord // or Replace on record
{
public int Id { get; }
public string Name { get; }
Expand Down
Loading

0 comments on commit 09a0e92

Please sign in to comment.