Skip to content

Commit

Permalink
fix MapsterMapper#327 RequireDestinationMemberSourc per type pair
Browse files Browse the repository at this point in the history
  • Loading branch information
chaowlert committed Apr 10, 2021
1 parent 1a6c142 commit 3012c14
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 12 deletions.
39 changes: 35 additions & 4 deletions src/Mapster.Core/Attributes/BaseAdaptAttribute.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;

namespace Mapster
{
Expand All @@ -10,23 +11,53 @@ public abstract class BaseAdaptAttribute : Attribute
protected BaseAdaptAttribute(Type type)
{
this.Type = type;
this.MapType = MapType.Map | MapType.MapToTarget;
}
protected BaseAdaptAttribute(string name)
{
this.Name = name;
this.MapType = MapType.Map | MapType.MapToTarget;
}

public Type? Type { get; }
public string? Name { get; }
public Type[]? IgnoreAttributes { get; set; }
public Type[]? IgnoreNoAttributes { get; set; }
public string[]? IgnoreNamespaces { get; set; }
public bool IgnoreNullValues { get; set; }
public bool MapToConstructor { get; set; }
public int MaxDepth { get; set; }
public bool PreserveReference { get; set; }
public bool ShallowCopyForSameType { get; set; }
public MapType MapType { get; set; }

private readonly Dictionary<string, bool> _boolValues = new Dictionary<string, bool>();
public bool IgnoreNullValues
{
get => _boolValues.TryGetValue(nameof(IgnoreNullValues), out var value) && value;
set => _boolValues[nameof(IgnoreNullValues)] = value;
}
public bool MapToConstructor
{
get => _boolValues.TryGetValue(nameof(MapToConstructor), out var value) && value;
set => _boolValues[nameof(MapToConstructor)] = value;
}
public bool PreserveReference
{
get => _boolValues.TryGetValue(nameof(PreserveReference), out var value) && value;
set => _boolValues[nameof(PreserveReference)] = value;
}
public bool ShallowCopyForSameType
{
get => _boolValues.TryGetValue(nameof(ShallowCopyForSameType), out var value) && value;
set => _boolValues[nameof(ShallowCopyForSameType)] = value;
}
public bool RequireDestinationMemberSource
{
get => _boolValues.TryGetValue(nameof(RequireDestinationMemberSource), out var value) && value;
set => _boolValues[nameof(RequireDestinationMemberSource)] = value;
}

public bool? GetBooleanSettingValues(string name)
{
return _boolValues.TryGetValue(name, out var value) ? (bool?)value : null;
}
}

public class AdaptFromAttribute : BaseAdaptAttribute
Expand Down
6 changes: 6 additions & 0 deletions src/Mapster.Core/Register/AdaptAttributeBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,12 @@ public AdaptAttributeBuilder IgnoreNullValues(bool value)
return this;
}

public AdaptAttributeBuilder RequireDestinationMemberSource(bool value)
{
this.Attribute.RequireDestinationMemberSource = value;
return this;
}

public AdaptAttributeBuilder MapToConstructor(bool value)
{
this.Attribute.MapToConstructor = value;
Expand Down
23 changes: 22 additions & 1 deletion src/Mapster.Tests/WhenHandlingUnmappedMembers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,32 @@ public void Error_Thrown_With_Explicit_Configuration_On_Unmapped_Primitive()
try
{
TypeAdapterConfig.GlobalSettings.RequireDestinationMemberSource = true;
TypeAdapterConfig<ParentPoco, ParentDto>.NewConfig().Compile();
TypeAdapterConfig<SimplePoco, SimpleDto>.NewConfig().Compile();

var source = new SimplePoco {Id = Guid.NewGuid(), Name = "TestName"};

TypeAdapter.Adapt<SimplePoco, SimpleDto>(source);
Assert.Fail();
}
catch (InvalidOperationException ex)
{
ex.ToString().ShouldContain("UnmappedMember");
}
}

[TestMethod]
public void Error_Thrown_With_Explicit_Setting_On_Unmapped_Primitive()
{
try
{
TypeAdapterConfig<SimplePoco, SimpleDto>.NewConfig()
.RequireDestinationMemberSource(true)
.Compile();

var source = new SimplePoco {Id = Guid.NewGuid(), Name = "TestName"};

TypeAdapter.Adapt<SimplePoco, SimpleDto>(source);
Assert.Fail();
}
catch (InvalidOperationException ex)
{
Expand Down
4 changes: 3 additions & 1 deletion src/Mapster/Adapters/BaseClassAdapter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,9 @@ select fn(src, destinationMember, arg))
}
}

if (arg.Context.Config.RequireDestinationMemberSource &&
var requireDestMemberSource = arg.Settings.RequireDestinationMemberSource ??
arg.Context.Config.RequireDestinationMemberSource;
if (requireDestMemberSource &&
unmappedDestinationMembers.Count > 0 &&
arg.Settings.SkipDestinationMemberCheck != true)
{
Expand Down
22 changes: 16 additions & 6 deletions src/Mapster/TypeAdapterSetter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,14 @@ public static TSetter AvoidInlineMapping<TSetter>(this TSetter setter, bool valu
return setter;
}

public static TSetter RequireDestinationMemberSource<TSetter>(this TSetter setter, bool value) where TSetter : TypeAdapterSetter
{
setter.CheckCompiled();

setter.Settings.RequireDestinationMemberSource = value;
return setter;
}

public static TSetter GetMemberName<TSetter>(this TSetter setter, Func<IMemberModel, string?> func) where TSetter : TypeAdapterSetter
{
setter.CheckCompiled();
Expand Down Expand Up @@ -291,16 +299,18 @@ public static TSetter ApplyAdaptAttribute<TSetter>(this TSetter setter, BaseAdap
setter.IgnoreMember((member, _) => member.Type.Namespace?.StartsWith(ns) == true);
}
}
if (attr.IgnoreNullValues)
setter.IgnoreNullValues(attr.IgnoreNullValues);
if (attr.MapToConstructor)
setter.MapToConstructor(attr.MapToConstructor);
if (attr.MaxDepth > 0)
setter.MaxDepth(attr.MaxDepth);
if (attr.PreserveReference)
if (attr.GetBooleanSettingValues(nameof(attr.IgnoreNullValues)) != null)
setter.IgnoreNullValues(attr.IgnoreNullValues);
if (attr.GetBooleanSettingValues(nameof(attr.MapToConstructor)) != null)
setter.MapToConstructor(attr.MapToConstructor);
if (attr.GetBooleanSettingValues(nameof(attr.PreserveReference)) != null)
setter.PreserveReference(attr.PreserveReference);
if (attr.ShallowCopyForSameType)
if (attr.GetBooleanSettingValues(nameof(attr.ShallowCopyForSameType)) != null)
setter.ShallowCopyForSameType(attr.ShallowCopyForSameType);
if (attr.GetBooleanSettingValues(nameof(attr.RequireDestinationMemberSource)) != null)
setter.RequireDestinationMemberSource(attr.RequireDestinationMemberSource);
return setter;
}
}
Expand Down
5 changes: 5 additions & 0 deletions src/Mapster/TypeAdapterSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ public bool? AvoidInlineMapping
get => Get(nameof(AvoidInlineMapping));
set => Set(nameof(AvoidInlineMapping), value);
}
public bool? RequireDestinationMemberSource
{
get => Get(nameof(RequireDestinationMemberSource));
set => Set(nameof(RequireDestinationMemberSource), value);
}
public int? MaxDepth
{
get => (int?) Get<object>(nameof(MaxDepth));
Expand Down

0 comments on commit 3012c14

Please sign in to comment.