Skip to content

Commit

Permalink
member side
Browse files Browse the repository at this point in the history
  • Loading branch information
chaowlert committed May 25, 2017
1 parent 3c02ccd commit c436564
Show file tree
Hide file tree
Showing 19 changed files with 124 additions and 50 deletions.
10 changes: 7 additions & 3 deletions src/Mapster.Tests/WhenMappingWithImplicitInheritance.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Shouldly;
using Mapster.Models;

namespace Mapster.Tests
{
Expand Down Expand Up @@ -178,7 +179,8 @@ public void Derived_Config_Shares_Base_Config_Properties()
//.MaxDepth(5)
.Compile();

var derivedConfig = TypeAdapterConfig.GlobalSettings.GetMergedSettings(typeof(DerivedPoco), typeof(SimpleDto), MapType.Map);
var tuple = new TypeTuple(typeof(DerivedPoco), typeof(SimpleDto));
var derivedConfig = TypeAdapterConfig.GlobalSettings.GetMergedSettings(tuple, MapType.Map);

derivedConfig.IgnoreNullValues.ShouldBe(true);
derivedConfig.ShallowCopyForSameType.ShouldBe(true);
Expand All @@ -195,7 +197,8 @@ public void Derived_Config_Shares_Base_Dest_Config_Properties()
//.MaxDepth(5)
.Compile();

var derivedConfig = TypeAdapterConfig.GlobalSettings.GetMergedSettings(typeof(DerivedPoco), typeof(DerivedDto), MapType.Map);
var tuple = new TypeTuple(typeof(DerivedPoco), typeof(DerivedDto));
var derivedConfig = TypeAdapterConfig.GlobalSettings.GetMergedSettings(tuple, MapType.Map);

derivedConfig.IgnoreNullValues.ShouldBe(true);
derivedConfig.ShallowCopyForSameType.ShouldBe(true);
Expand All @@ -212,7 +215,8 @@ public void Derived_Config_Doesnt_Share_Base_Dest_Config_Properties_If_Disabled(
//.MaxDepth(5)
.Compile();

var derivedConfig = TypeAdapterConfig.GlobalSettings.GetMergedSettings(typeof(DerivedPoco), typeof(DerivedDto), MapType.Map);
var tuple = new TypeTuple(typeof(DerivedPoco), typeof(DerivedDto));
var derivedConfig = TypeAdapterConfig.GlobalSettings.GetMergedSettings(tuple, MapType.Map);

derivedConfig.IgnoreNullValues.ShouldBeNull();
derivedConfig.ShallowCopyForSameType.ShouldBeNull();
Expand Down
2 changes: 1 addition & 1 deletion src/Mapster/Adapters/BaseClassAdapter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ protected static bool ProcessIgnores(
out LambdaExpression condition)
{
condition = null;
if (!destinationMember.ShouldMapMember(config.ShouldMapMember))
if (!destinationMember.ShouldMapMember(config.ShouldMapMember, MemberSide.Destination))
return true;

return config.IgnoreIfs.TryGetValue(destinationMember.Name, out condition)
Expand Down
2 changes: 1 addition & 1 deletion src/Mapster/Adapters/DictionaryAdapter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ protected override ClassModel GetClassModel(Type destinationType, CompileArgumen
.Where(name => name != null)
.ToHashSet();
var propNames = arg.SourceType.GetFieldsAndProperties(accessorFlags: BindingFlags.NonPublic | BindingFlags.Public)
.Where(model => model.ShouldMapMember(arg.Settings.ShouldMapMember))
.Where(model => model.ShouldMapMember(arg.Settings.ShouldMapMember, MemberSide.Source))
.Select(model => model.Name)
.Where(name => !srcNames.Contains(name))
.Select(name => arg.Settings.NameMatchingStrategy.SourceMemberNameConverter(name));
Expand Down
14 changes: 14 additions & 0 deletions src/Mapster/Enums/MemberSide.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Mapster
{
public enum MemberSide
{
Source,
Destination,
}
}
2 changes: 2 additions & 0 deletions src/Mapster/Mapster.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,13 @@
<Compile Include="Compile\CompileContext.cs" />
<Compile Include="Compile\CompileException.cs" />
<Compile Include="Enums\EnumMappingStrategy.cs" />
<Compile Include="Enums\MemberSide.cs" />
<Compile Include="Interfaces\IApplyable.cs" />
<Compile Include="Interfaces\IRegister.cs" />
<Compile Include="MapContext\MapContext.cs" />
<Compile Include="MapContext\MapContextScope.cs" />
<Compile Include="Enums\MapType.cs" />
<Compile Include="Models\IMemberModelEx.cs" />
<Compile Include="Models\KeyValuePairModel.cs" />
<Compile Include="Settings\GetMemberName.cs" />
<Compile Include="Settings\NameMatchingStrategy.cs" />
Expand Down
2 changes: 1 addition & 1 deletion src/Mapster/Models/ClassModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ namespace Mapster.Models
internal class ClassModel
{
public ConstructorInfo ConstructorInfo { get; set; }
public IEnumerable<IMemberModel> Members { get; set; }
public IEnumerable<IMemberModelEx> Members { get; set; }
}
}
2 changes: 1 addition & 1 deletion src/Mapster/Models/FieldModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

namespace Mapster.Models
{
public class FieldModel : IMemberModel
public class FieldModel : IMemberModelEx
{
private readonly FieldInfo _fieldInfo;
public FieldModel(FieldInfo fieldInfo)
Expand Down
2 changes: 0 additions & 2 deletions src/Mapster/Models/IMemberModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ public interface IMemberModel
AccessModifier SetterModifier { get; }
AccessModifier AccessModifier { get; }

Expression GetExpression(Expression source);
Expression SetExpression(Expression source, Expression value);
IEnumerable<object> GetCustomAttributes(bool inherit);
}
}
10 changes: 10 additions & 0 deletions src/Mapster/Models/IMemberModelEx.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using System.Linq.Expressions;

namespace Mapster.Models
{
internal interface IMemberModelEx: IMemberModel
{
Expression GetExpression(Expression source);
Expression SetExpression(Expression source, Expression value);
}
}
4 changes: 2 additions & 2 deletions src/Mapster/Models/KeyValuePairModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@

namespace Mapster.Models
{
public class KeyValuePairModel : IMemberModel
public class KeyValuePairModel : IMemberModelEx
{
readonly Func<Expression, Expression, Expression> _getFn;
readonly Func<Expression, Expression, Expression, Expression> _setFn;
public KeyValuePairModel(string name, Type type,
public KeyValuePairModel(string name, Type type,
Func<Expression, Expression, Expression> getFn,
Func<Expression, Expression, Expression, Expression> setFn)
{
Expand Down
2 changes: 1 addition & 1 deletion src/Mapster/Models/MemberMapping.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ namespace Mapster.Models
internal class MemberMapping
{
public Expression Getter;
public IMemberModel DestinationMember;
public IMemberModelEx DestinationMember;
public LambdaExpression SetterCondition;
}
}
2 changes: 1 addition & 1 deletion src/Mapster/Models/ParameterModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

namespace Mapster.Models
{
public class ParameterModel : IMemberModel
public class ParameterModel : IMemberModelEx
{
private readonly ParameterInfo _parameterInfo;
public ParameterModel(ParameterInfo parameterInfo)
Expand Down
2 changes: 1 addition & 1 deletion src/Mapster/Models/PropertyModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

namespace Mapster.Models
{
public class PropertyModel : IMemberModel
public class PropertyModel : IMemberModelEx
{
protected readonly PropertyInfo _propertyInfo;
public PropertyModel(PropertyInfo propertyInfo)
Expand Down
8 changes: 4 additions & 4 deletions src/Mapster/Settings/ShouldMapMember.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ namespace Mapster
{
public static class ShouldMapMember
{
public static Func<IMemberModel, bool?> AllowNonPublic = model => model.AccessModifier != AccessModifier.None;
public static Func<IMemberModel, bool?> AllowPublic = model => model.AccessModifier == AccessModifier.Public ? (bool?)true : null;
public static Func<IMemberModel, bool?> IgnoreAdaptIgnore = model => model.HasCustomAttribute(typeof(AdaptIgnoreAttribute)) ? (bool?)false : null;
public static Func<IMemberModel, bool?> AllowAdaptMember = model => model.HasCustomAttribute(typeof(AdaptMemberAttribute)) ? (bool?)true : null;
public static Func<IMemberModel, MemberSide, bool?> AllowNonPublic = (model, _) => model.AccessModifier != AccessModifier.None;
public static Func<IMemberModel, MemberSide, bool?> AllowPublic = (model, _) => model.AccessModifier == AccessModifier.Public ? (bool?)true : null;
public static Func<IMemberModel, MemberSide, bool?> IgnoreAdaptIgnore = (model, _) => model.HasCustomAttribute(typeof(AdaptIgnoreAttribute)) ? (bool?)false : null;
public static Func<IMemberModel, MemberSide, bool?> AllowAdaptMember = (model, _) => model.HasCustomAttribute(typeof(AdaptMemberAttribute)) ? (bool?)true : null;
}
}
2 changes: 1 addition & 1 deletion src/Mapster/Settings/ValueAccessingStrategy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ private static Expression PropertyOrFieldFn(Expression source, IMemberModel dest
var strategy = arg.Settings.NameMatchingStrategy;
var destinationMemberName = destinationMember.GetMemberName(arg.Settings.GetMemberNames, strategy.DestinationMemberNameConverter);
return members
.Where(member => member.ShouldMapMember(arg.Settings.ShouldMapMember))
.Where(member => member.ShouldMapMember(arg.Settings.ShouldMapMember, MemberSide.Source))
.Where(member => member.GetMemberName(arg.Settings.GetMemberNames, strategy.SourceMemberNameConverter) == destinationMemberName)
.Select(member => member.GetExpression(source))
.FirstOrDefault();
Expand Down
20 changes: 10 additions & 10 deletions src/Mapster/TypeAdapterConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ internal LambdaExpression CreateMapExpression(TypeTuple tuple, MapType mapType)
context.Running.Add(tuple);
try
{
var arg = GetCompileArgument(tuple.Source, tuple.Destination, mapType, context);
var arg = GetCompileArgument(tuple, mapType, context);
return CreateMapExpression(arg);
}
finally
Expand Down Expand Up @@ -365,7 +365,7 @@ internal LambdaExpression CreateInlineMapExpression(Type sourceType, Type destin
context.Running.Add(tuple);
try
{
var arg = GetCompileArgument(tuple.Source, tuple.Destination, parentMapType == MapType.Projection ? MapType.Projection : MapType.InlineMap, context);
var arg = GetCompileArgument(tuple, parentMapType == MapType.Projection ? MapType.Projection : MapType.InlineMap, context);
var exp = CreateMapExpression(arg);
if (exp != null)
{
Expand Down Expand Up @@ -419,10 +419,10 @@ private LambdaExpression CreateMapToTargetInvokeExpression(Type sourceType, Type
return Expression.Lambda(invoke, p1, p2);
}

internal TypeAdapterSettings GetMergedSettings(Type sourceType, Type destinationType, MapType mapType)
internal TypeAdapterSettings GetMergedSettings(TypeTuple tuple, MapType mapType)
{
var settings = (from rule in this.Rules.Reverse<TypeAdapterRule>()
let priority = rule.Priority(sourceType, destinationType, mapType)
let priority = rule.Priority(tuple.Source, tuple.Destination, mapType)
where priority != null
orderby priority.Value descending
select rule.Settings).ToList();
Expand All @@ -434,19 +434,19 @@ orderby priority.Value descending

//remove recursive include types
if (mapType == MapType.MapToTarget)
result.Includes.Remove(new TypeTuple(sourceType, destinationType));
result.Includes.Remove(tuple);
else
result.Includes.RemoveAll(tuple => tuple.Source == sourceType);
result.Includes.RemoveAll(t => t.Source == tuple.Source);
return result;
}

CompileArgument GetCompileArgument(Type sourceType, Type destinationType, MapType mapType, CompileContext context)
CompileArgument GetCompileArgument(TypeTuple tuple, MapType mapType, CompileContext context)
{
var setting = GetMergedSettings(sourceType, destinationType, mapType);
var setting = GetMergedSettings(tuple, mapType);
var arg = new CompileArgument
{
SourceType = sourceType,
DestinationType = destinationType,
SourceType = tuple.Source,
DestinationType = tuple.Destination,
MapType = mapType,
Context = context,
Settings = setting,
Expand Down
72 changes: 59 additions & 13 deletions src/Mapster/TypeAdapterSetter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,16 +50,35 @@ public static TSetter IgnoreAttribute<TSetter>(this TSetter setter, params Type[

foreach (var type in types)
{
setter.Settings.ShouldMapMember.Add(member => member.HasCustomAttribute(type) ? (bool?)false : null);
setter.Settings.ShouldMapMember.Add((member, _) => member.HasCustomAttribute(type) ? (bool?)false : null);
}
return setter;
}

public static TSetter ShouldMapMember<TSetter>(this TSetter setter, Func<IMemberModel, bool> predicate, bool value) where TSetter : TypeAdapterSetter
public static TSetter IncludeAttribute<TSetter>(this TSetter setter, params Type[] types) where TSetter : TypeAdapterSetter
{
setter.CheckCompiled();

setter.Settings.ShouldMapMember.Add(member => predicate(member) ? (bool?)value : null);
foreach (var type in types)
{
setter.Settings.ShouldMapMember.Add((member, _) => member.HasCustomAttribute(type) ? (bool?)true : null);
}
return setter;
}

public static TSetter IgnoreMember<TSetter>(this TSetter setter, Func<IMemberModel, MemberSide, bool> predicate) where TSetter : TypeAdapterSetter
{
setter.CheckCompiled();

setter.Settings.ShouldMapMember.Add((member, side) => predicate(member, side) ? (bool?)false : null);
return setter;
}

public static TSetter IncludeMember<TSetter>(this TSetter setter, Func<IMemberModel, MemberSide, bool> predicate) where TSetter : TypeAdapterSetter
{
setter.CheckCompiled();

setter.Settings.ShouldMapMember.Add((member, side) => predicate(member, side) ? (bool?)true : null);
return setter;
}

Expand Down Expand Up @@ -116,7 +135,10 @@ public static TSetter Map<TSetter, TSourceMember>(
Invoker = invoker,
Condition = null
});
setter.Settings.ShouldMapMember.Add(member => member.Name == memberName ? (bool?)true : null);
setter.Settings.ShouldMapMember.Add((member, side) =>
(member.Name == memberName && side == MemberSide.Destination)
? (bool?)true
: null);

return setter;
}
Expand All @@ -134,7 +156,10 @@ public static TSetter Map<TSetter, TSource, TSourceMember>(
SourceMemberName = ReflectionUtils.GetMemberInfo(source, true)?.Member.Name,
Condition = null
});
setter.Settings.ShouldMapMember.Add(member => member.Name == memberName ? (bool?)true : null);
setter.Settings.ShouldMapMember.Add((member, side) =>
(member.Name == memberName && side == MemberSide.Destination)
? (bool?)true
: null);

return setter;
}
Expand All @@ -150,9 +175,24 @@ public static TSetter Map<TSetter>(
SourceMemberName = sourceMemberName,
Condition = null
});
setter.Settings.ShouldMapMember.Add(member => member.Name == destinationMemberName ? (bool?)true : null);
if (sourceMemberName != destinationMemberName)
setter.Settings.ShouldMapMember.Add(member => member.Name == sourceMemberName ? (bool?)true : null);
{
setter.Settings.ShouldMapMember.Add((member, side) =>
(member.Name == destinationMemberName && side == MemberSide.Destination)
? (bool?)true
: null);
setter.Settings.ShouldMapMember.Add((member, side) =>
(member.Name == sourceMemberName && side == MemberSide.Source)
? (bool?)true
: null);
}
else
{
setter.Settings.ShouldMapMember.Add((member, _) =>
member.Name == destinationMemberName
? (bool?)true
: null);
}

return setter;
}
Expand All @@ -163,13 +203,13 @@ public static TSetter EnableNonPublicMembers<TSetter>(this TSetter setter, bool

if (value)
{
setter.Settings.ShouldMapMember.Remove(Mapster.ShouldMapMember.AllowPublic);
setter.Settings.ShouldMapMember.Add(Mapster.ShouldMapMember.AllowNonPublic);
setter.Settings.ShouldMapMember.Remove(ShouldMapMember.AllowPublic);
setter.Settings.ShouldMapMember.Add(ShouldMapMember.AllowNonPublic);
}
else
{
setter.Settings.ShouldMapMember.Remove(Mapster.ShouldMapMember.AllowNonPublic);
setter.Settings.ShouldMapMember.Add(Mapster.ShouldMapMember.AllowPublic);
setter.Settings.ShouldMapMember.Remove(ShouldMapMember.AllowNonPublic);
setter.Settings.ShouldMapMember.Add(ShouldMapMember.AllowPublic);
}

return setter;
Expand Down Expand Up @@ -247,7 +287,10 @@ public TypeAdapterSetter<TDestination> Map<TDestinationMember>(
SourceMemberName = sourceMemberName,
Condition = null
});
Settings.ShouldMapMember.Add(member => member.Name == sourceMemberName ? (bool?)true : null);
Settings.ShouldMapMember.Add((member, side) =>
(member.Name == sourceMemberName && side == MemberSide.Source)
? (bool?)true
: null);

return this;
}
Expand Down Expand Up @@ -375,7 +418,10 @@ public TypeAdapterSetter<TSource, TDestination> Map<TSourceMember>(
SourceMemberName = ReflectionUtils.GetMemberInfo(source, true)?.Member.Name,
Condition = shouldMap
});
Settings.ShouldMapMember.Add(member => member.Name == memberName ? (bool?)true : null);
Settings.ShouldMapMember.Add((member, side) =>
(member.Name == memberName && side == MemberSide.Destination)
? (bool?)true
: null);

return this;
}
Expand Down
4 changes: 2 additions & 2 deletions src/Mapster/TypeAdapterSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,9 @@ public bool? AvoidInlineMapping
set => Set("AvoidInlineMapping", value);
}

public List<Func<IMemberModel, bool?>> ShouldMapMember
public List<Func<IMemberModel, MemberSide, bool?>> ShouldMapMember
{
get => Get("ShouldMapMember", () => new List<Func<IMemberModel, bool?>>());
get => Get("ShouldMapMember", () => new List<Func<IMemberModel, MemberSide, bool?>>());
}
public List<Func<Expression, IMemberModel, CompileArgument, Expression>> ValueAccessingStrategies
{
Expand Down
Loading

0 comments on commit c436564

Please sign in to comment.