Browse Source

Refactor MappingPropertyDefinitionChecks

pull/3431/head
Halil İbrahim Kalkan 6 years ago
parent
commit
9698e3f7dc
  1. 2
      framework/src/Volo.Abp.AutoMapper/AutoMapper/AbpAutoMapperExtensibleDtoExtensions.cs
  2. 135
      framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/HasExtraPropertiesObjectExtendingExtensions.cs
  3. 14
      framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ObjectExtensionPropertyInfo.cs
  4. 1
      framework/test/Volo.Abp.ObjectExtending.Tests/Volo/Abp/ObjectExtending/AbpObjectExtendingTestModule.cs
  5. 4
      framework/test/Volo.Abp.ObjectExtending.Tests/Volo/Abp/ObjectExtending/HasExtraPropertiesObjectExtendingExtensions_Tests.cs

2
framework/src/Volo.Abp.AutoMapper/AutoMapper/AbpAutoMapperExtensibleDtoExtensions.cs

@ -8,7 +8,7 @@ namespace AutoMapper
{
public static IMappingExpression<TSource, TDestination> MapExtraProperties<TSource, TDestination>(
this IMappingExpression<TSource, TDestination> mappingExpression,
MappingPropertyDefinitionChecks definitionChecks = MappingPropertyDefinitionChecks.Both)
MappingPropertyDefinitionChecks? definitionChecks = null)
where TDestination : IHasExtraProperties
where TSource : IHasExtraProperties
{

135
framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/HasExtraPropertiesObjectExtendingExtensions.cs

@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using JetBrains.Annotations;
using Volo.Abp.Data;
@ -25,7 +24,7 @@ namespace Volo.Abp.ObjectExtending
public static void MapExtraPropertiesTo<TSource, TDestination>(
[NotNull] this TSource source,
[NotNull] TDestination destination,
MappingPropertyDefinitionChecks definitionChecks = MappingPropertyDefinitionChecks.Both)
MappingPropertyDefinitionChecks? definitionChecks = null)
where TSource : IHasExtraProperties
where TDestination : IHasExtraProperties
{
@ -58,7 +57,7 @@ namespace Volo.Abp.ObjectExtending
public static void MapExtraPropertiesTo<TSource, TDestination>(
[NotNull] Dictionary<string, object> sourceDictionary,
[NotNull] Dictionary<string, object> destinationDictionary,
MappingPropertyDefinitionChecks definitionChecks = MappingPropertyDefinitionChecks.Both)
MappingPropertyDefinitionChecks? definitionChecks = null)
where TSource : IHasExtraProperties
where TDestination : IHasExtraProperties
{
@ -90,7 +89,7 @@ namespace Volo.Abp.ObjectExtending
[NotNull] Type destinationType,
[NotNull] Dictionary<string, object> sourceDictionary,
[NotNull] Dictionary<string, object> destinationDictionary,
MappingPropertyDefinitionChecks definitionChecks = MappingPropertyDefinitionChecks.Both)
MappingPropertyDefinitionChecks? definitionChecks = null)
{
Check.AssignableTo<IHasExtraProperties>(sourceType, nameof(sourceType));
Check.AssignableTo<IHasExtraProperties>(destinationType, nameof(destinationType));
@ -98,78 +97,120 @@ namespace Volo.Abp.ObjectExtending
Check.NotNull(destinationDictionary, nameof(destinationDictionary));
var sourceObjectExtension = ObjectExtensionManager.Instance.GetOrNull(sourceType);
if (definitionChecks.HasFlag(MappingPropertyDefinitionChecks.Source) &&
sourceObjectExtension == null)
{
return;
}
var destinationObjectExtension = ObjectExtensionManager.Instance.GetOrNull(destinationType);
if (definitionChecks.HasFlag(MappingPropertyDefinitionChecks.Destination) &&
destinationObjectExtension == null)
{
return;
}
if (definitionChecks == MappingPropertyDefinitionChecks.None)
foreach (var keyValue in sourceDictionary)
{
foreach (var keyValue in sourceDictionary)
if (CanMapProperty(
keyValue.Key,
sourceObjectExtension,
destinationObjectExtension,
definitionChecks))
{
destinationDictionary[keyValue.Key] = keyValue.Value;
}
}
else if (definitionChecks == MappingPropertyDefinitionChecks.Source)
{
Debug.Assert(sourceObjectExtension != null, nameof(sourceObjectExtension) + " != null");
}
//TODO: Move these methods to a class like ObjectExtensionHelper
public static bool CanMapProperty<TSource, TDestination>(
[NotNull] string propertyName,
MappingPropertyDefinitionChecks? definitionChecks = null)
{
return CanMapProperty(
typeof(TSource),
typeof(TDestination),
propertyName,
definitionChecks
);
}
public static bool CanMapProperty(
[NotNull] Type sourceType,
[NotNull] Type destinationType,
[NotNull] string propertyName,
MappingPropertyDefinitionChecks? definitionChecks = null)
{
Check.AssignableTo<IHasExtraProperties>(sourceType, nameof(sourceType));
Check.AssignableTo<IHasExtraProperties>(destinationType, nameof(destinationType));
Check.NotNull(propertyName, nameof(propertyName));
var sourceObjectExtension = ObjectExtensionManager.Instance.GetOrNull(sourceType);
var destinationObjectExtension = ObjectExtensionManager.Instance.GetOrNull(destinationType);
return CanMapProperty(
propertyName,
sourceObjectExtension,
destinationObjectExtension,
definitionChecks);
}
foreach (var property in sourceObjectExtension.GetProperties())
private static bool CanMapProperty(
[NotNull] string propertyName,
[CanBeNull] ObjectExtensionInfo sourceObjectExtension,
[CanBeNull] ObjectExtensionInfo destinationObjectExtension,
MappingPropertyDefinitionChecks? definitionChecks = null)
{
Check.NotNull(propertyName, nameof(propertyName));
if (definitionChecks != null)
{
if (definitionChecks.Value.HasFlag(MappingPropertyDefinitionChecks.Source))
{
if (!sourceDictionary.ContainsKey(property.Name))
if (sourceObjectExtension == null)
{
continue;
return false;
}
destinationDictionary[property.Name] = sourceDictionary[property.Name];
if (!sourceObjectExtension.HasProperty(propertyName))
{
return false;
}
}
}
else if (definitionChecks == MappingPropertyDefinitionChecks.Destination)
{
Debug.Assert(destinationObjectExtension != null, nameof(destinationObjectExtension) + " != null");
foreach (var keyValue in sourceDictionary)
if (definitionChecks.Value.HasFlag(MappingPropertyDefinitionChecks.Destination))
{
if (!destinationObjectExtension.HasProperty(keyValue.Key))
if (destinationObjectExtension == null)
{
continue;
return false;
}
destinationDictionary[keyValue.Key] = keyValue.Value;
if (!destinationObjectExtension.HasProperty(propertyName))
{
return false;
}
}
return true;
}
else if (definitionChecks == MappingPropertyDefinitionChecks.Both)
else
{
Debug.Assert(sourceObjectExtension != null, nameof(sourceObjectExtension) + " != null");
Debug.Assert(destinationObjectExtension != null, nameof(destinationObjectExtension) + " != null");
var sourcePropertyDefinition = sourceObjectExtension?.GetPropertyOrNull(propertyName);
var destinationPropertyDefinition = destinationObjectExtension?.GetPropertyOrNull(propertyName);
foreach (var property in sourceObjectExtension.GetProperties())
if (sourcePropertyDefinition != null)
{
if (!sourceDictionary.ContainsKey(property.Name))
if (destinationPropertyDefinition != null)
{
continue;
return true;
}
if (!destinationObjectExtension.HasProperty(property.Name))
if (sourcePropertyDefinition.CheckPairDefinitionOnMapping == false)
{
continue;
return true;
}
destinationDictionary[property.Name] = sourceDictionary[property.Name];
}
}
else
{
throw new NotImplementedException(definitionChecks + " was not implemented!");
else if (destinationPropertyDefinition != null)
{
if (destinationPropertyDefinition.CheckPairDefinitionOnMapping == false)
{
return true;
}
}
return false;
}
}
}
}
}

14
framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ObjectExtensionPropertyInfo.cs

@ -15,6 +15,20 @@ namespace Volo.Abp.ObjectExtending
[NotNull]
public Type Type { get; }
/// <summary>
/// Indicates whether to check the other side of the object mapping
/// if it explicitly defines the property. This property is used in;
///
/// * .MapExtraPropertiesTo() extension method.
/// * .MapExtraProperties() configuration for the AutoMapper.
///
/// It this is true, these methods check if the mapping object
/// has defined the property using the <see cref="ObjectExtensionManager"/>.
///
/// Default: null (unspecified, uses the default logic).
/// </summary>
public bool? CheckPairDefinitionOnMapping { get; set; }
[NotNull]
public Dictionary<object, object> Configuration { get; }

1
framework/test/Volo.Abp.ObjectExtending.Tests/Volo/Abp/ObjectExtending/AbpObjectExtendingTestModule.cs

@ -19,6 +19,7 @@ namespace Volo.Abp.ObjectExtending
ObjectExtensionManager.Instance
.AddOrUpdateProperty<ExtensibleTestPerson, string>("Name")
.AddOrUpdateProperty<ExtensibleTestPerson, int>("Age")
.AddOrUpdateProperty<ExtensibleTestPerson, string>("NoPairCheck", options => options.CheckPairDefinitionOnMapping = false)
.AddOrUpdateProperty<ExtensibleTestPersonDto, string>("Name")
.AddOrUpdateProperty<ExtensibleTestPersonDto, int>("ChildCount");
});

4
framework/test/Volo.Abp.ObjectExtending.Tests/Volo/Abp/ObjectExtending/HasExtraPropertiesObjectExtendingExtensions_Tests.cs

@ -16,7 +16,8 @@ namespace Volo.Abp.ObjectExtending
.SetProperty("Name", "John")
.SetProperty("Age", 42)
.SetProperty("ChildCount", 2)
.SetProperty("Sex", "male");
.SetProperty("Sex", "male")
.SetProperty("NoPairCheck", "test-value");
_personDto = new ExtensibleTestPersonDto()
.SetProperty("ExistingDtoProperty", "existing-value");
@ -31,6 +32,7 @@ namespace Volo.Abp.ObjectExtending
_personDto.HasProperty("Age").ShouldBeFalse(); //Not defined on the destination
_personDto.HasProperty("ChildCount").ShouldBeFalse(); //Not defined in the source
_personDto.HasProperty("Sex").ShouldBeFalse(); //Not defined in both classes
_personDto.GetProperty<string>("NoPairCheck").ShouldBe("test-value"); //CheckPairDefinitionOnMapping = false
_personDto.GetProperty<string>("ExistingDtoProperty").ShouldBe("existing-value"); //Should not clear existing values
}

Loading…
Cancel
Save