Skip to content

Commit

Permalink
code review, remove useInterfaceHierarchy
Browse files Browse the repository at this point in the history
  • Loading branch information
chaowlert committed Jan 19, 2020
1 parent 6cf5e15 commit 5158f08
Show file tree
Hide file tree
Showing 10 changed files with 28 additions and 129 deletions.
53 changes: 2 additions & 51 deletions src/Mapster.Tests/WhenMappingToInterface.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public void MapToInterface()
}

[TestMethod]
public void MapToInheritedInterface_InterfaceHierarchyEnabled()
public void MapToInheritedInterface()
{
var dto = new InheritedDto
{
Expand All @@ -47,7 +47,6 @@ public void MapToInheritedInterface_InterfaceHierarchyEnabled()
};

var config = new TypeAdapterConfig();
config.Default.UseInterfaceHierarchy(true);

IInheritedDto idto = dto.Adapt<IInheritedDto>(config);

Expand All @@ -61,7 +60,7 @@ public void MapToInheritedInterface_InterfaceHierarchyEnabled()
}

[TestMethod]
public void MapToInheritedInterface_InterfaceHierarchyDisabled()
public void MapToInstanceWithInterface()
{
var dto = new InheritedDto
{
Expand All @@ -73,31 +72,6 @@ public void MapToInheritedInterface_InterfaceHierarchyDisabled()

var config = new TypeAdapterConfig();

IInheritedDto idto = dto.Adapt<IInheritedDto>(config);

idto.ShouldNotBeNull();
idto.ShouldSatisfyAllConditions(
() => idto.Id.ShouldBe(default),
() => idto.Name.ShouldBeNull(),
() => idto.DateOfBirth.ShouldBe(dto.DateOfBirth),
() => idto.UnmappedTarget.ShouldBeNull()
);
}

[TestMethod]
public void MapToInstanceWithInterface_InterfaceHierarchyEnabled()
{
var dto = new InheritedDto
{
Id = 1,
Name = "Test",
DateOfBirth = new DateTime(1978, 12, 10),
UnmappedSource = "Lorem ipsum"
};

var config = new TypeAdapterConfig();
config.Default.UseInterfaceHierarchy(true);

IInheritedDto target = new ImplementedDto();
dto.Adapt(target, config);

Expand All @@ -110,29 +84,6 @@ public void MapToInstanceWithInterface_InterfaceHierarchyEnabled()
);
}

[TestMethod]
public void MapToInstanceWithInterface_InterfaceHierarchyDisabled()
{
var dto = new InheritedDto
{
Id = 1,
Name = "Test",
DateOfBirth = new DateTime(1978, 12, 10),
UnmappedSource = "Lorem ipsum"
};

IInheritedDto target = new ImplementedDto();
dto.Adapt(target);

target.ShouldNotBeNull();
target.ShouldSatisfyAllConditions(
() => target.Id.ShouldBe(default),
() => target.Name.ShouldBeNull(),
() => target.DateOfBirth.ShouldBe(dto.DateOfBirth),
() => target.UnmappedTarget.ShouldBeNull()
);
}

[TestMethod]
public void MapToComplexInterface()
{
Expand Down
6 changes: 1 addition & 5 deletions src/Mapster/Adapters/BaseAdapter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -333,11 +333,7 @@ protected virtual Expression CreateInstantiationExpression(Expression source, Ex
}

//if mapping to interface, create dynamic type implementing it
#if NETSTANDARD1_3
else if (destination is null && arg.DestinationType.IsInterface())
#else
else if (destination is null && arg.DestinationType.IsInterface)
#endif
else if (arg.DestinationType.GetTypeInfo().IsInterface)
{
return Expression.New(DynamicTypeGenerator.GetTypeForInterface(arg.DestinationType));
}
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 @@ -171,7 +171,7 @@ protected virtual ClassModel GetSetterModel(CompileArgument arg)
{
return new ClassModel
{
Members = arg.DestinationType.GetFieldsAndProperties(useInterfaceHierarchy: arg.Settings.UseInterfaceHierarchy, requireSetter: true, accessorFlags: BindingFlags.NonPublic | BindingFlags.Public)
Members = arg.DestinationType.GetFieldsAndProperties(requireSetter: true, accessorFlags: BindingFlags.NonPublic | BindingFlags.Public)
};
}

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 @@ -175,7 +175,7 @@ protected override ClassModel GetSetterModel(CompileArgument arg)
if (arg.SourceType.GetDictionaryType() == null)
{
var srcNames = arg.GetSourceNames();
var propNames = arg.SourceType.GetFieldsAndProperties(useInterfaceHierarchy: arg.Settings.UseInterfaceHierarchy, accessorFlags: BindingFlags.NonPublic | BindingFlags.Public)
var propNames = arg.SourceType.GetFieldsAndProperties(accessorFlags: BindingFlags.NonPublic | BindingFlags.Public)
.Where(model => model.ShouldMapMember(arg, MemberSide.Source))
.Select(model => model.Name)
.Where(name => !srcNames.Contains(name))
Expand Down
8 changes: 4 additions & 4 deletions src/Mapster/Settings/ValueAccessingStrategy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ public static class ValueAccessingStrategy

private static Expression? PropertyOrFieldFn(Expression source, IMemberModel destinationMember, CompileArgument arg)
{
var members = source.Type.GetFieldsAndProperties(useInterfaceHierarchy: arg.Settings.UseInterfaceHierarchy, accessorFlags: BindingFlags.NonPublic | BindingFlags.Public);
var members = source.Type.GetFieldsAndProperties(accessorFlags: BindingFlags.NonPublic | BindingFlags.Public);
var strategy = arg.Settings.NameMatchingStrategy;
var destinationMemberName = destinationMember.GetMemberName(arg.Settings.GetMemberNames, strategy.DestinationMemberNameConverter);
return members
Expand Down Expand Up @@ -110,7 +110,7 @@ public static class ValueAccessingStrategy
private static Expression? GetDeepFlattening(Expression source, string propertyName, CompileArgument arg)
{
var strategy = arg.Settings.NameMatchingStrategy;
var members = source.Type.GetFieldsAndProperties(useInterfaceHierarchy: arg.Settings.UseInterfaceHierarchy, accessorFlags: BindingFlags.NonPublic | BindingFlags.Public);
var members = source.Type.GetFieldsAndProperties(accessorFlags: BindingFlags.NonPublic | BindingFlags.Public);
foreach (var member in members)
{
if (!member.ShouldMapMember(arg, MemberSide.Source))
Expand All @@ -137,7 +137,7 @@ internal static IEnumerable<InvokerModel> FindUnflatteningPairs(Expression sourc
{
var strategy = arg.Settings.NameMatchingStrategy;
var destinationMemberName = destinationMember.GetMemberName(arg.Settings.GetMemberNames, strategy.DestinationMemberNameConverter);
var members = source.Type.GetFieldsAndProperties(useInterfaceHierarchy: arg.Settings.UseInterfaceHierarchy, accessorFlags: BindingFlags.NonPublic | BindingFlags.Public);
var members = source.Type.GetFieldsAndProperties(accessorFlags: BindingFlags.NonPublic | BindingFlags.Public);

foreach (var member in members)
{
Expand All @@ -160,7 +160,7 @@ internal static IEnumerable<InvokerModel> FindUnflatteningPairs(Expression sourc
private static IEnumerable<string> GetDeepUnflattening(IMemberModel destinationMember, string propertyName, CompileArgument arg)
{
var strategy = arg.Settings.NameMatchingStrategy;
var members = destinationMember.Type.GetFieldsAndProperties(useInterfaceHierarchy: arg.Settings.UseInterfaceHierarchy, accessorFlags: BindingFlags.NonPublic | BindingFlags.Public);
var members = destinationMember.Type.GetFieldsAndProperties(accessorFlags: BindingFlags.NonPublic | BindingFlags.Public);
foreach (var member in members)
{
if (!member.ShouldMapMember(arg, MemberSide.Destination))
Expand Down
2 changes: 1 addition & 1 deletion src/Mapster/TypeAdapter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public static TDestination Adapt<TDestination>(this object source)
public static TDestination Adapt<TDestination>(this object source, TypeAdapterConfig config)
{
if (source == null)
return default(TDestination)!;
return default!;
var type = source.GetType();
var fn = config.GetDynamicMapFunction<TDestination>(type);
return fn(source);
Expand Down
16 changes: 0 additions & 16 deletions src/Mapster/TypeAdapterSetter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
using System.Reflection;
using Mapster.Adapters;
using Mapster.Models;
using Mapster.Utils;

namespace Mapster
{
Expand Down Expand Up @@ -236,14 +235,6 @@ public static class TypeAdapterSetterExtensions
setter.Settings.Unflattening = value;
return setter;
}

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

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

public class TypeAdapterSetter<TDestination> : TypeAdapterSetter
Expand Down Expand Up @@ -816,12 +807,5 @@ public TwoWaysTypeAdapterSetter(TypeAdapterConfig config)
DestinationToSourceSetter.MaxDepth(value);
return this;
}

public TwoWaysTypeAdapterSetter<TSource, TDestination> UseInterfaceHierarchy(bool value)
{
SourceToDestinationSetter.UseInterfaceHierarchy(value);
DestinationToSourceSetter.UseInterfaceHierarchy(value);
return this;
}
}
}
6 changes: 0 additions & 6 deletions src/Mapster/TypeAdapterSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,6 @@ public NameMatchingStrategy NameMatchingStrategy
set => Set("SkipDestinationMemberCheck", value);
}

public bool? UseInterfaceHierarchy
{
get => Get(nameof(UseInterfaceHierarchy));
set => Set(nameof(UseInterfaceHierarchy), value);
}

public List<Func<IMemberModel, MemberSide, bool?>> ShouldMapMember
{
get => Get("ShouldMapMember", () => new List<Func<IMemberModel, MemberSide, bool?>>());
Expand Down
29 changes: 8 additions & 21 deletions src/Mapster/Utils/DynamicTypeGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,36 +18,23 @@ internal static class DynamicTypeGenerator
#endif
private static readonly ModuleBuilder _moduleBuilder = _assemblyBuilder.DefineDynamicModule("Classes");
private static readonly ConcurrentDictionary<Type, Type> _generated = new ConcurrentDictionary<Type, Type>();
private static int _generatedCounter = 0;
private static int _generatedCounter;

public static Type GetTypeForInterface(Type interfaceType)
{
CheckInterfaceType(interfaceType);
return _generated.GetOrAdd(interfaceType, (key) => CreateTypeForInterface(key));
}

private static void CheckInterfaceType(Type interfaceType)
{
#if NETSTANDARD1_3
if (!interfaceType.IsInterface())
#else
if (!interfaceType.IsInterface)
#endif
if (!interfaceType.GetTypeInfo().IsInterface)
{
const string msg = "Cannot create dynamic type for {0}, because it is not an interface.\n" +
"Target type full name: {1}";
"Target type full name: {1}";
throw new InvalidOperationException(string.Format(msg, interfaceType.Name, interfaceType.FullName));
}
#if NETSTANDARD1_3
if (!interfaceType.IsVisible())
#else
if (!interfaceType.IsVisible)
#endif
if (!interfaceType.GetTypeInfo().IsVisible)
{
const string msg = "Cannot adapt to interface {0}, because it is not accessible outside its assembly.\n" +
"Interface full name: {1}";
"Interface full name: {1}";
throw new InvalidOperationException(string.Format(msg, interfaceType.Name, interfaceType.FullName));
}
return _generated.GetOrAdd(interfaceType, CreateTypeForInterface);
}

private static Type CreateTypeForInterface(Type interfaceType)
Expand All @@ -72,7 +59,7 @@ private static Type CreateTypeForInterface(Type interfaceType)
}

#if NETSTANDARD2_0
return builder.CreateTypeInfo();
return builder.CreateTypeInfo()!;
#elif NETSTANDARD1_3
return builder.CreateTypeInfo().AsType();
#else
Expand Down Expand Up @@ -124,7 +111,7 @@ private static void CreateProperty(Type interfaceType, TypeBuilder builder, Prop

private static void CreateMethod(TypeBuilder builder, MethodInfo interfaceMethod)
{
Type[] parameterTypes = null;
Type[]? parameterTypes = null;
ParameterInfo[] parameters = interfaceMethod.GetParameters();
if (parameters.Length > 0)
{
Expand Down
33 changes: 10 additions & 23 deletions src/Mapster/Utils/ReflectionUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,6 @@ public static IEnumerable<CustomAttributeData> GetCustomAttributesData(this Memb
{
return member.CustomAttributes;
}
public static bool IsInterface(this Type type) => type.GetTypeInfo().IsInterface;
public static bool IsVisible(this Type type) => type.GetTypeInfo().IsVisible;
#endif

public static bool IsNullable(this Type type)
Expand All @@ -79,12 +77,10 @@ public static bool IsPoco(this Type type)
if (type.IsConvertible())
return false;

return type.GetFieldsAndProperties(useInterfaceHierarchy: true, requireSetter: true).Any();
return type.GetFieldsAndProperties(requireSetter: true).Any();
}

public static IEnumerable<IMemberModelEx> GetFieldsAndProperties(
this Type type,
bool? useInterfaceHierarchy,
public static IEnumerable<IMemberModelEx> GetFieldsAndProperties(this Type type,
bool requireSetter = false,
BindingFlags accessorFlags = BindingFlags.Public)
{
Expand All @@ -99,33 +95,24 @@ IEnumerable<IMemberModelEx> getFieldsFunc(Type t) => t.GetFields(bindingFlags)
.Where(x => !requireSetter || !x.IsInitOnly)
.Select(CreateModel);

IEnumerable<IMemberModelEx> properties;
IEnumerable<IMemberModelEx> fields;

#if NETSTANDARD1_3
if (type.IsInterface() && (useInterfaceHierarchy == true))
#else
if (type.IsInterface && (useInterfaceHierarchy == true))
#endif
if (type.GetTypeInfo().IsInterface)
{
IEnumerable<Type> allInterfaces = GetAllInterfaces(type);
properties = allInterfaces.SelectMany(currentInterface => getPropertiesFunc(currentInterface));
fields = allInterfaces.SelectMany(currentInterface => getFieldsFunc(currentInterface));
var allInterfaces = GetAllInterfaces(type);
return allInterfaces.SelectMany(getPropertiesFunc);
}
else
{
properties = getPropertiesFunc(type);
fields = getFieldsFunc(type);
var properties = getPropertiesFunc(type);
var fields = getFieldsFunc(type);
return properties.Concat(fields);
}

return properties.Concat(fields);
}

// GetProperties(), GetFields(), GetMethods() do not return properties/methods from parent interfaces,
// so we need to process every one of them separately.
public static IEnumerable<Type> GetAllInterfaces(Type interfaceType)
{
var allInterfaces = new List<Type>();
var allInterfaces = new HashSet<Type>();
var interfaceQueue = new Queue<Type>();
allInterfaces.Add(interfaceType);
interfaceQueue.Enqueue(interfaceType);
Expand Down Expand Up @@ -236,7 +223,7 @@ public static bool IsRecordType(this Type type)
return false;

//no public setter
var props = type.GetFieldsAndProperties(useInterfaceHierarchy: true).ToList();
var props = type.GetFieldsAndProperties().ToList();
if (props.Any(p => p.SetterModifier == AccessModifier.Public))
return false;

Expand Down

0 comments on commit 5158f08

Please sign in to comment.