mirror of https://github.com/abpframework/abp.git
8 changed files with 291 additions and 200 deletions
@ -0,0 +1,237 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using JetBrains.Annotations; |
|||
using Volo.Abp.Data; |
|||
|
|||
namespace Volo.Abp.ObjectExtending |
|||
{ |
|||
public static class ExtensibleObjectMapper |
|||
{ |
|||
/// <summary>
|
|||
/// Copies extra properties from the <paramref name="source"/> object
|
|||
/// to the <paramref name="destination"/> object.
|
|||
///
|
|||
/// Checks property definitions (over the <see cref="ObjectExtensionManager"/>)
|
|||
/// based on the <paramref name="definitionChecks"/> preference.
|
|||
/// </summary>
|
|||
/// <typeparam name="TSource">Source class type</typeparam>
|
|||
/// <typeparam name="TDestination">Destination class type</typeparam>
|
|||
/// <param name="source">The source object</param>
|
|||
/// <param name="destination">The destination object</param>
|
|||
/// <param name="definitionChecks">
|
|||
/// Controls which properties to map.
|
|||
/// </param>
|
|||
/// <param name="ignoredProperties">Used to ignore some properties</param>
|
|||
public static void MapExtraPropertiesTo<TSource, TDestination>( |
|||
[NotNull] TSource source, |
|||
[NotNull] TDestination destination, |
|||
MappingPropertyDefinitionChecks? definitionChecks = null, |
|||
string[] ignoredProperties = null) |
|||
where TSource : IHasExtraProperties |
|||
where TDestination : IHasExtraProperties |
|||
{ |
|||
Check.NotNull(source, nameof(source)); |
|||
Check.NotNull(destination, nameof(destination)); |
|||
|
|||
ExtensibleObjectMapper.MapExtraPropertiesTo( |
|||
typeof(TSource), |
|||
typeof(TDestination), |
|||
source.ExtraProperties, |
|||
destination.ExtraProperties, |
|||
definitionChecks, |
|||
ignoredProperties |
|||
); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Copies extra properties from the <paramref name="sourceDictionary"/> object
|
|||
/// to the <paramref name="destinationDictionary"/> object.
|
|||
///
|
|||
/// Checks property definitions (over the <see cref="ObjectExtensionManager"/>)
|
|||
/// based on the <paramref name="definitionChecks"/> preference.
|
|||
/// </summary>
|
|||
/// <typeparam name="TSource">Source class type (for definition check)</typeparam>
|
|||
/// <typeparam name="TDestination">Destination class type (for definition check)</typeparam>
|
|||
/// <param name="sourceDictionary">The source dictionary object</param>
|
|||
/// <param name="destinationDictionary">The destination dictionary object</param>
|
|||
/// <param name="definitionChecks">
|
|||
/// Controls which properties to map.
|
|||
/// </param>
|
|||
/// <param name="ignoredProperties">Used to ignore some properties</param>
|
|||
public static void MapExtraPropertiesTo<TSource, TDestination>( |
|||
[NotNull] Dictionary<string, object> sourceDictionary, |
|||
[NotNull] Dictionary<string, object> destinationDictionary, |
|||
MappingPropertyDefinitionChecks? definitionChecks = null, |
|||
string[] ignoredProperties = null) |
|||
where TSource : IHasExtraProperties |
|||
where TDestination : IHasExtraProperties |
|||
{ |
|||
MapExtraPropertiesTo( |
|||
typeof(TSource), |
|||
typeof(TDestination), |
|||
sourceDictionary, |
|||
destinationDictionary, |
|||
definitionChecks, |
|||
ignoredProperties |
|||
); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Copies extra properties from the <paramref name="sourceDictionary"/> object
|
|||
/// to the <paramref name="destinationDictionary"/> object.
|
|||
///
|
|||
/// Checks property definitions (over the <see cref="ObjectExtensionManager"/>)
|
|||
/// based on the <paramref name="definitionChecks"/> preference.
|
|||
/// </summary>
|
|||
/// <param name="sourceType">Source type (for definition check)</param>
|
|||
/// <param name="destinationType">Destination class type (for definition check)</param>
|
|||
/// <param name="sourceDictionary">The source dictionary object</param>
|
|||
/// <param name="destinationDictionary">The destination dictionary object</param>
|
|||
/// <param name="definitionChecks">
|
|||
/// Controls which properties to map.
|
|||
/// </param>
|
|||
/// <param name="ignoredProperties">Used to ignore some properties</param>
|
|||
public static void MapExtraPropertiesTo( |
|||
[NotNull] Type sourceType, |
|||
[NotNull] Type destinationType, |
|||
[NotNull] Dictionary<string, object> sourceDictionary, |
|||
[NotNull] Dictionary<string, object> destinationDictionary, |
|||
MappingPropertyDefinitionChecks? definitionChecks = null, |
|||
string[] ignoredProperties = null) |
|||
{ |
|||
Check.AssignableTo<IHasExtraProperties>(sourceType, nameof(sourceType)); |
|||
Check.AssignableTo<IHasExtraProperties>(destinationType, nameof(destinationType)); |
|||
Check.NotNull(sourceDictionary, nameof(sourceDictionary)); |
|||
Check.NotNull(destinationDictionary, nameof(destinationDictionary)); |
|||
|
|||
var sourceObjectExtension = ObjectExtensionManager.Instance.GetOrNull(sourceType); |
|||
var destinationObjectExtension = ObjectExtensionManager.Instance.GetOrNull(destinationType); |
|||
|
|||
foreach (var keyValue in sourceDictionary) |
|||
{ |
|||
if (CanMapProperty( |
|||
keyValue.Key, |
|||
sourceObjectExtension, |
|||
destinationObjectExtension, |
|||
definitionChecks, |
|||
ignoredProperties)) |
|||
{ |
|||
destinationDictionary[keyValue.Key] = keyValue.Value; |
|||
} |
|||
} |
|||
} |
|||
|
|||
//TODO: Move these methods to a class like ObjectExtensionHelper
|
|||
|
|||
public static bool CanMapProperty<TSource, TDestination>( |
|||
[NotNull] string propertyName, |
|||
MappingPropertyDefinitionChecks? definitionChecks = null, |
|||
string[] ignoredProperties = null) |
|||
{ |
|||
return CanMapProperty( |
|||
typeof(TSource), |
|||
typeof(TDestination), |
|||
propertyName, |
|||
definitionChecks, |
|||
ignoredProperties |
|||
); |
|||
} |
|||
|
|||
public static bool CanMapProperty( |
|||
[NotNull] Type sourceType, |
|||
[NotNull] Type destinationType, |
|||
[NotNull] string propertyName, |
|||
MappingPropertyDefinitionChecks? definitionChecks = null, |
|||
string[] ignoredProperties = 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, |
|||
ignoredProperties); |
|||
} |
|||
|
|||
private static bool CanMapProperty( |
|||
[NotNull] string propertyName, |
|||
[CanBeNull] ObjectExtensionInfo sourceObjectExtension, |
|||
[CanBeNull] ObjectExtensionInfo destinationObjectExtension, |
|||
MappingPropertyDefinitionChecks? definitionChecks = null, |
|||
string[] ignoredProperties = null) |
|||
{ |
|||
Check.NotNull(propertyName, nameof(propertyName)); |
|||
|
|||
if (ignoredProperties != null && |
|||
ignoredProperties.Contains(propertyName)) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
if (definitionChecks != null) |
|||
{ |
|||
if (definitionChecks.Value.HasFlag(MappingPropertyDefinitionChecks.Source)) |
|||
{ |
|||
if (sourceObjectExtension == null) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
if (!sourceObjectExtension.HasProperty(propertyName)) |
|||
{ |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
if (definitionChecks.Value.HasFlag(MappingPropertyDefinitionChecks.Destination)) |
|||
{ |
|||
if (destinationObjectExtension == null) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
if (!destinationObjectExtension.HasProperty(propertyName)) |
|||
{ |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
return true; |
|||
} |
|||
else |
|||
{ |
|||
var sourcePropertyDefinition = sourceObjectExtension?.GetPropertyOrNull(propertyName); |
|||
var destinationPropertyDefinition = destinationObjectExtension?.GetPropertyOrNull(propertyName); |
|||
|
|||
if (sourcePropertyDefinition != null) |
|||
{ |
|||
if (destinationPropertyDefinition != null) |
|||
{ |
|||
return true; |
|||
} |
|||
|
|||
if (sourcePropertyDefinition.CheckPairDefinitionOnMapping == false) |
|||
{ |
|||
return true; |
|||
} |
|||
} |
|||
else if (destinationPropertyDefinition != null) |
|||
{ |
|||
if (destinationPropertyDefinition.CheckPairDefinitionOnMapping == false) |
|||
{ |
|||
return true; |
|||
} |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue