Skip to content

Commit

Permalink
cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
chaowlert committed Apr 5, 2019
1 parent 4ee4ca2 commit 2baedae
Show file tree
Hide file tree
Showing 13 changed files with 54 additions and 46 deletions.
5 changes: 0 additions & 5 deletions src/Benchmark/CustomerMapper.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@






using System.Collections.Generic;
using Benchmark.Classes;

Expand Down
8 changes: 3 additions & 5 deletions src/Benchmark/CustomerMapper.tt
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
<#@ template debug="true" language="C#" #>
<#@ output extension=".cs" #>

<# /*@ Assembly Name="/usr/local/share/dotnet/sdk/2.2.103/Microsoft/Microsoft.NET.Build.Extensions/net461/lib/netstandard.dll" */ #>
<#@ Assembly Name="netstandard" #>
<#@ Assembly Name="System.Core" #>
Expand All @@ -9,10 +8,9 @@
<#@ Assembly Name="$(TargetDir)/Benchmark.dll" #>
<#@ Assembly Name="$(TargetDir)/Mapster.dll" #>
<#@ Assembly Name="$(TargetDir)/ExpressionTranslator.dll" #>
<#@ import namespace="Benchmark.Classes" #>
<#@ import namespace="ExpressionDebugger" #>
<#@ import namespace="Mapster" #>

<#@ import namespace="Benchmark.Classes" #>
<#@ import namespace="ExpressionDebugger" #>
<#@ import namespace="Mapster" #>
<#
TypeAdapterConfig.GlobalSettings.SelfContainedCodeGeneration = true;
var foo = default(Customer);
Expand Down
5 changes: 0 additions & 5 deletions src/Benchmark/FooMapper.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@






using System;
using System.Linq;
using Benchmark.Classes;
Expand Down
8 changes: 3 additions & 5 deletions src/Benchmark/FooMapper.tt
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
<#@ template debug="true" language="C#" #>
<#@ output extension=".cs" #>

<# /*@ Assembly Name="/usr/local/share/dotnet/sdk/2.2.103/Microsoft/Microsoft.NET.Build.Extensions/net461/lib/netstandard.dll" */ #>
<#@ Assembly Name="netstandard" #>
<#@ Assembly Name="System.Core" #>
Expand All @@ -9,10 +8,9 @@
<#@ Assembly Name="$(TargetDir)/Benchmark.dll" #>
<#@ Assembly Name="$(TargetDir)/Mapster.dll" #>
<#@ Assembly Name="$(TargetDir)/ExpressionTranslator.dll" #>
<#@ import namespace="Benchmark.Classes" #>
<#@ import namespace="ExpressionDebugger" #>
<#@ import namespace="Mapster" #>

<#@ import namespace="Benchmark.Classes" #>
<#@ import namespace="ExpressionDebugger" #>
<#@ import namespace="Mapster" #>
<#
TypeAdapterConfig.GlobalSettings.SelfContainedCodeGeneration = true;
var foo = default(Foo);
Expand Down
20 changes: 14 additions & 6 deletions src/Mapster/Adapters/BaseClassAdapter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,12 @@ protected ClassMapping CreateClassConverter(Expression source, ClassModel classM
else if (classModel.ConstructorInfo != null)
{
var info = (ParameterInfo)destinationMember.Info;
if (!info.IsOptional && !classModel.AllowDefault)
return null;
if (!info.IsOptional)
{
if (classModel.BreakOnUnmatched)
return null;
unmappedDestinationMembers.Add(destinationMember.Name);
}
var propertyModel = new MemberMapping
{
Getter = null,
Expand All @@ -58,11 +62,15 @@ protected ClassMapping CreateClassConverter(Expression source, ClassModel classM
}
else if (destinationMember.SetterModifier != AccessModifier.None)
{
if (classModel.BreakOnUnmatched)
return null;
unmappedDestinationMembers.Add(destinationMember.Name);
}
}

if (arg.Context.Config.RequireDestinationMemberSource && unmappedDestinationMembers.Count > 0)
if (arg.Context.Config.RequireDestinationMemberSource &&
unmappedDestinationMembers.Count > 0 &&
arg.Settings.SkipDestinationMemberCheck != true)
{
throw new InvalidOperationException($"The following members of destination class {arg.DestinationType} do not have a corresponding source member mapped or ignored:{string.Join(",", unmappedDestinationMembers)}");
}
Expand Down Expand Up @@ -126,11 +134,11 @@ protected Expression CreateInstantiationExpression(Expression source, ClassMappi
return Expression.New(classConverter.ConstructorInfo, arguments);
}

protected virtual ClassModel GetConstructorModel(ConstructorInfo ctor, bool allowDefault)
protected virtual ClassModel GetConstructorModel(ConstructorInfo ctor, bool breakOnUnmatched)
{
return new ClassModel
{
AllowDefault = allowDefault,
BreakOnUnmatched = breakOnUnmatched,
ConstructorInfo = ctor,
Members = ctor.GetParameters().Select(ReflectionUtils.CreateModel)
};
Expand All @@ -140,7 +148,7 @@ protected virtual ClassModel GetSetterModel(CompileArgument arg)
{
return new ClassModel
{
Members = arg.DestinationType.GetFieldsAndProperties(allowNoSetter: false, accessorFlags: BindingFlags.NonPublic | BindingFlags.Public)
Members = arg.DestinationType.GetFieldsAndProperties(requireSetter: true, accessorFlags: BindingFlags.NonPublic | BindingFlags.Public)
};
}

Expand Down
4 changes: 2 additions & 2 deletions src/Mapster/Adapters/ClassAdapter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,13 @@ protected override Expression CreateInstantiationExpression(Expression source, E
{
classConverter = arg.DestinationType.GetConstructors()
.OrderByDescending(it => it.GetParameters().Length)
.Select(it => GetConstructorModel(it, false))
.Select(it => GetConstructorModel(it, true))
.Select(it => CreateClassConverter(source, it, arg))
.FirstOrDefault(it => it != null);
}
else
{
var model = GetConstructorModel(ctor, true);
var model = GetConstructorModel(ctor, false);
classConverter = CreateClassConverter(source, model, arg);
}

Expand Down
2 changes: 1 addition & 1 deletion src/Mapster/Adapters/RecordTypeAdapter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ protected override Expression CreateInstantiationExpression(Expression source, E
return base.CreateInstantiationExpression(source, destination, arg);

var ctor = arg.DestinationType.GetConstructors()[0];
var classModel = GetConstructorModel(ctor, true);
var classModel = GetConstructorModel(ctor, false);
var classConverter = CreateClassConverter(source, classModel, arg);
return CreateInstantiationExpression(source, classConverter, arg);
}
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 @@ -5,7 +5,7 @@ namespace Mapster.Models
{
internal class ClassModel
{
public bool AllowDefault { get; set; }
public bool BreakOnUnmatched { get; set; }
public ConstructorInfo ConstructorInfo { get; set; }
public IEnumerable<IMemberModelEx> Members { get; set; }
}
Expand Down
2 changes: 1 addition & 1 deletion src/Mapster/Settings/GetMemberName.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@ namespace Mapster
{
public static class GetMemberName
{
public static Func<IMemberModel, string> AdaptMember = model => model.GetCustomAttribute<AdaptMemberAttribute>()?.Name;
public static readonly Func<IMemberModel, string> AdaptMember = model => model.GetCustomAttribute<AdaptMemberAttribute>()?.Name;
}
}
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, 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;
public static readonly Func<IMemberModel, MemberSide, bool?> AllowNonPublic = (model, _) => model.AccessModifier != AccessModifier.None;
public static readonly Func<IMemberModel, MemberSide, bool?> AllowPublic = (model, _) => model.AccessModifier == AccessModifier.Public ? (bool?)true : null;
public static readonly Func<IMemberModel, MemberSide, bool?> IgnoreAdaptIgnore = (model, _) => model.HasCustomAttribute(typeof(AdaptIgnoreAttribute)) ? (bool?)false : null;
public static readonly Func<IMemberModel, MemberSide, bool?> AllowAdaptMember = (model, _) => model.HasCustomAttribute(typeof(AdaptMemberAttribute)) ? (bool?)true : null;
}
}
15 changes: 12 additions & 3 deletions src/Mapster/TypeAdapterSetter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ public TypeAdapterSetter<TDestination> Ignore(params Expression<Func<TDestinatio

foreach (var member in members)
{
Settings.IgnoreIfs[ReflectionUtils.GetMemberPath(member, true)] = null;
Settings.IgnoreIfs[ReflectionUtils.GetMemberPath(member)] = null;
}
return this;
}
Expand Down Expand Up @@ -404,7 +404,7 @@ internal TypeAdapterSetter(TypeAdapterSettings settings, TypeAdapterConfig paren

foreach (var member in members)
{
var name = ReflectionUtils.GetMemberPath(member, true);
var name = ReflectionUtils.GetMemberPath(member);
Settings.IgnoreIfs.Merge(name, condition);
}
return this;
Expand Down Expand Up @@ -545,6 +545,14 @@ internal TypeAdapterSetter(TypeAdapterSettings settings, TypeAdapterConfig paren
return this;
}

public TypeAdapterSetter<TSource, TDestination> BeforeMappingInline(Expression<Func<TSource, TDestination, TDestination>> action)
{
this.CheckCompiled();

Settings.BeforeMappingFactories.Add(arg => action);
return this;
}

public TypeAdapterSetter<TSource, TDestination> AfterMappingInline(Expression<Action<TSource, TDestination>> action)
{
this.CheckCompiled();
Expand Down Expand Up @@ -619,6 +627,7 @@ public TwoWaysTypeAdapterSetter(TypeAdapterConfig config)
.Unflattening(true);
DestinationToSourceSetter = config.ForType<TDestination, TSource>()
.Unflattening(true);
DestinationToSourceSetter.Settings.SkipDestinationMemberCheck = true;
}

public TwoWaysTypeAdapterSetter<TSource, TDestination> AddDestinationTransform<TDestinationMember>(Expression<Func<TDestinationMember, TDestinationMember>> transform)
Expand Down Expand Up @@ -761,7 +770,7 @@ public TwoWaysTypeAdapterSetter(TypeAdapterConfig config)
{
foreach (var member in members)
{
var path = ReflectionUtils.GetMemberPath(member, true);
var path = ReflectionUtils.GetMemberPath(member);
this.Ignore(path);
}
return this;
Expand Down
5 changes: 5 additions & 0 deletions src/Mapster/TypeAdapterSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@ public NameMatchingStrategy NameMatchingStrategy
get => Get("Unflattening");
set => Set("Unflattening", value);
}
public bool? SkipDestinationMemberCheck
{
get => Get("SkipDestinationMemberCheck");
set => Set("SkipDestinationMemberCheck", value);
}

public List<Func<IMemberModel, MemberSide, bool?>> ShouldMapMember
{
Expand Down
16 changes: 8 additions & 8 deletions src/Mapster/Utils/ReflectionUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,20 +55,20 @@ public static bool IsPoco(this Type type)
if (type.IsConvertible())
return false;

return type.GetFieldsAndProperties(allowNoSetter: false).Any();
return type.GetFieldsAndProperties(requireSetter: true).Any();
}

public static IEnumerable<IMemberModelEx> GetFieldsAndProperties(this Type type, bool allowNoSetter = true, BindingFlags accessorFlags = BindingFlags.Public)
public static IEnumerable<IMemberModelEx> GetFieldsAndProperties(this Type type, bool requireSetter = false, BindingFlags accessorFlags = BindingFlags.Public)
{
var bindingFlags = BindingFlags.Instance | accessorFlags;

var properties = type.GetProperties(bindingFlags)
.Where(x => x.GetIndexParameters().Length == 0)
.Where(x => allowNoSetter || x.CanWrite)
.Where(x => !requireSetter || x.CanWrite)
.Select(CreateModel);

var fields = type.GetFields(bindingFlags)
.Where(x => allowNoSetter || !x.IsInitOnly)
.Where(x => !requireSetter || !x.IsInitOnly)
.Select(CreateModel);

return properties.Concat(fields);
Expand All @@ -94,12 +94,12 @@ public static bool IsGenericEnumerableType(this Type type)
return type.GetTypeInfo().IsGenericType && type.GetGenericTypeDefinition() == typeof(IEnumerable<>);
}

public static Type GetInterface(this Type type, Func<Type, bool> predicate)
public static Type GetInterface(this Type type, Predicate<Type> predicate)
{
if (predicate(type))
return type;

return type.GetInterfaces().FirstOrDefault(predicate);
return Array.Find(type.GetInterfaces(), predicate);
}

public static Type GetGenericEnumerableType(this Type type)
Expand Down Expand Up @@ -137,7 +137,7 @@ public static string GetMemberPath(LambdaExpression lambda, bool firstLevelOnly
{
if (noError)
return null;
throw new ArgumentException("Only first level members are allowed (eg. obj => obj.Child)", nameof(expr));
throw new ArgumentException("Only first level members are allowed (eg. obj => obj.Child)", nameof(lambda));
}

var memEx = (MemberExpression)expr;
Expand All @@ -148,7 +148,7 @@ public static string GetMemberPath(LambdaExpression lambda, bool firstLevelOnly
{
if (noError)
return null;
throw new ArgumentException("Allow only member access (eg. obj => obj.Child.Name)", nameof(expr));
throw new ArgumentException("Allow only member access (eg. obj => obj.Child.Name)", nameof(lambda));
}
props.Reverse();
return string.Join(".", props);
Expand Down

0 comments on commit 2baedae

Please sign in to comment.