Refactor ObjectExtending.

pull/3401/head
Halil İbrahim Kalkan 5 years ago
parent 0053c02946
commit edf8f82fc2

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

@ -69,14 +69,17 @@ namespace Volo.Abp.EntityFrameworkCore.Modeling
}
public static void ConfigureObjectExtensions<T>(this EntityTypeBuilder<T> b)
where T : class
where T : class, IHasExtraProperties
{
b.As<EntityTypeBuilder>().TryConfigureObjectExtensions();
}
public static void TryConfigureObjectExtensions(this EntityTypeBuilder b)
{
ObjectExtensionManager.Instance.ConfigureEfCoreEntity(b);
if (b.Metadata.ClrType.IsAssignableTo<IHasExtraProperties>())
{
ObjectExtensionManager.Instance.ConfigureEfCoreEntity(b);
}
}
public static void ConfigureSoftDelete<T>(this EntityTypeBuilder<T> b)

@ -1,5 +1,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using JetBrains.Annotations;
using Volo.Abp.Data;
namespace Volo.Abp.ObjectExtending
@ -11,26 +13,31 @@ namespace Volo.Abp.ObjectExtending
/// to the <paramref name="destination"/> object.
///
/// Checks property definitions (over the <see cref="ObjectExtensionManager"/>)
/// based on the <paramref name="definitionCheck"/> preference.
/// 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="definitionCheck">
/// <param name="definitionChecks">
/// Controls which properties to map.
/// </param>
public static void MapExtraPropertiesTo<TSource, TDestination>(
this TSource source,
TDestination destination,
MappingPropertyDefinitionCheck definitionCheck = MappingPropertyDefinitionCheck.Both)
[NotNull] this TSource source,
[NotNull] TDestination destination,
MappingPropertyDefinitionChecks definitionChecks = MappingPropertyDefinitionChecks.Both)
where TSource : IHasExtraProperties
where TDestination : IHasExtraProperties
{
MapExtraPropertiesTo<TSource, TDestination>(
Check.NotNull(source, nameof(source));
Check.NotNull(destination, nameof(destination));
MapExtraPropertiesTo(
typeof(TSource),
typeof(TDestination),
source.ExtraProperties,
destination.ExtraProperties,
definitionCheck
definitionChecks
);
}
@ -39,45 +46,82 @@ namespace Volo.Abp.ObjectExtending
/// to the <paramref name="destinationDictionary"/> object.
///
/// Checks property definitions (over the <see cref="ObjectExtensionManager"/>)
/// based on the <paramref name="definitionCheck"/> preference.
/// 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="definitionCheck">
/// <param name="definitionChecks">
/// Controls which properties to map.
/// </param>
public static void MapExtraPropertiesTo<TSource, TDestination>(
Dictionary<string, object> sourceDictionary,
Dictionary<string, object> destinationDictionary,
MappingPropertyDefinitionCheck definitionCheck = MappingPropertyDefinitionCheck.Both)
[NotNull] Dictionary<string, object> sourceDictionary,
[NotNull] Dictionary<string, object> destinationDictionary,
MappingPropertyDefinitionChecks definitionChecks = MappingPropertyDefinitionChecks.Both)
where TSource : IHasExtraProperties
where TDestination : IHasExtraProperties
{
var sourceObjectExtension = ObjectExtensionManager.Instance.GetOrNull<TSource>();
if (definitionCheck.HasFlag(MappingPropertyDefinitionCheck.Source) &&
MapExtraPropertiesTo(
typeof(TSource),
typeof(TDestination),
sourceDictionary,
destinationDictionary,
definitionChecks
);
}
/// <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>
public static void MapExtraPropertiesTo(
[NotNull] Type sourceType,
[NotNull] Type destinationType,
[NotNull] Dictionary<string, object> sourceDictionary,
[NotNull] Dictionary<string, object> destinationDictionary,
MappingPropertyDefinitionChecks definitionChecks = MappingPropertyDefinitionChecks.Both)
{
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);
if (definitionChecks.HasFlag(MappingPropertyDefinitionChecks.Source) &&
sourceObjectExtension == null)
{
return;
}
var destinationObjectExtension = ObjectExtensionManager.Instance.GetOrNull<TDestination>();
if (definitionCheck.HasFlag(MappingPropertyDefinitionCheck.Destination) &&
var destinationObjectExtension = ObjectExtensionManager.Instance.GetOrNull(destinationType);
if (definitionChecks.HasFlag(MappingPropertyDefinitionChecks.Destination) &&
destinationObjectExtension == null)
{
return;
}
if (definitionCheck == MappingPropertyDefinitionCheck.None)
if (definitionChecks == MappingPropertyDefinitionChecks.None)
{
foreach (var keyValue in sourceDictionary)
{
destinationDictionary[keyValue.Key] = keyValue.Value;
}
}
else if (definitionCheck == MappingPropertyDefinitionCheck.Source)
else if (definitionChecks == MappingPropertyDefinitionChecks.Source)
{
Debug.Assert(sourceObjectExtension != null, nameof(sourceObjectExtension) + " != null");
foreach (var property in sourceObjectExtension.GetProperties())
{
if (!sourceDictionary.ContainsKey(property.Name))
@ -88,8 +132,10 @@ namespace Volo.Abp.ObjectExtending
destinationDictionary[property.Name] = sourceDictionary[property.Name];
}
}
else if (definitionCheck == MappingPropertyDefinitionCheck.Destination)
else if (definitionChecks == MappingPropertyDefinitionChecks.Destination)
{
Debug.Assert(destinationObjectExtension != null, nameof(destinationObjectExtension) + " != null");
foreach (var keyValue in sourceDictionary)
{
if (!destinationObjectExtension.HasProperty(keyValue.Key))
@ -100,8 +146,11 @@ namespace Volo.Abp.ObjectExtending
destinationDictionary[keyValue.Key] = keyValue.Value;
}
}
else if (definitionCheck == MappingPropertyDefinitionCheck.Both)
else if (definitionChecks == MappingPropertyDefinitionChecks.Both)
{
Debug.Assert(sourceObjectExtension != null, nameof(sourceObjectExtension) + " != null");
Debug.Assert(destinationObjectExtension != null, nameof(destinationObjectExtension) + " != null");
foreach (var property in sourceObjectExtension.GetProperties())
{
if (!sourceDictionary.ContainsKey(property.Name))
@ -119,7 +168,7 @@ namespace Volo.Abp.ObjectExtending
}
else
{
throw new NotImplementedException(definitionCheck + " was not implemented!");
throw new NotImplementedException(definitionChecks + " was not implemented!");
}
}
}

@ -3,7 +3,7 @@
namespace Volo.Abp.ObjectExtending
{
[Flags]
public enum MappingPropertyDefinitionCheck : byte
public enum MappingPropertyDefinitionChecks : byte
{
/// <summary>
/// No check. Copy all extra properties from the source to the destination.

@ -2,20 +2,24 @@
using System.Collections.Generic;
using System.Collections.Immutable;
using JetBrains.Annotations;
using Volo.Abp.Data;
namespace Volo.Abp.ObjectExtending
{
public class ObjectExtensionInfo
{
[NotNull]
public Type Type { get; }
[NotNull]
protected Dictionary<string, ObjectExtensionPropertyInfo> Properties { get; }
[NotNull]
public Dictionary<object, object> Configuration { get; }
public ObjectExtensionInfo(Type type)
public ObjectExtensionInfo([NotNull] Type type)
{
Type = type;
Type = Check.AssignableTo<IHasExtraProperties>(type, nameof(type));
Properties = new Dictionary<string, ObjectExtensionPropertyInfo>();
Configuration = new Dictionary<object, object>();
}
@ -25,6 +29,7 @@ namespace Volo.Abp.ObjectExtending
return Properties.ContainsKey(propertyName);
}
[NotNull]
public virtual ObjectExtensionInfo AddOrUpdateProperty<TProperty>(
[NotNull] string propertyName,
[CanBeNull] Action<ObjectExtensionPropertyInfo> configureAction = null)
@ -36,6 +41,7 @@ namespace Volo.Abp.ObjectExtending
);
}
[NotNull]
public virtual ObjectExtensionInfo AddOrUpdateProperty(
[NotNull] Type propertyType,
[NotNull] string propertyName,
@ -54,6 +60,7 @@ namespace Volo.Abp.ObjectExtending
return this;
}
[NotNull]
public virtual ImmutableList<ObjectExtensionPropertyInfo> GetProperties()
{
return Properties.Values.ToImmutableList();

@ -16,6 +16,7 @@ namespace Volo.Abp.ObjectExtending
ObjectsExtensions = new Dictionary<Type, ObjectExtensionInfo>();
}
[NotNull]
public virtual ObjectExtensionManager AddOrUpdate<TObject>(
[CanBeNull] Action<ObjectExtensionInfo> configureAction = null)
where TObject : IHasExtraProperties
@ -23,12 +24,13 @@ namespace Volo.Abp.ObjectExtending
return AddOrUpdate(typeof(TObject), configureAction);
}
[NotNull]
public virtual ObjectExtensionManager AddOrUpdate(
[NotNull] Type type,
[CanBeNull] Action<ObjectExtensionInfo> configureAction = null)
{
Check.NotNull(type, nameof(type));
Check.AssignableTo<IHasExtraProperties>(type, nameof(type));
var extensionInfo = ObjectsExtensions.GetOrAdd(
type,
() => new ObjectExtensionInfo(type)
@ -39,14 +41,17 @@ namespace Volo.Abp.ObjectExtending
return this;
}
[CanBeNull]
public virtual ObjectExtensionInfo GetOrNull<TObject>()
where TObject : IHasExtraProperties
{
return GetOrNull(typeof(TObject));
}
[CanBeNull]
public virtual ObjectExtensionInfo GetOrNull([NotNull] Type type)
{
Check.NotNull(type, nameof(type));
Check.AssignableTo<IHasExtraProperties>(type, nameof(type));
return ObjectsExtensions.GetOrDefault(type);
}

@ -15,19 +15,18 @@ namespace Volo.Abp.ObjectExtending
[NotNull]
public Type Type { get; }
//[NotNull] //TODO: Will be implemented, probably in the v2.5
//public List<ValidationAttribute> ValidationAttributes { get; }
[NotNull]
public Dictionary<object, object> Configuration { get; }
public ObjectExtensionPropertyInfo([NotNull] ObjectExtensionInfo objectExtension, [NotNull] Type type, [NotNull] string name)
public ObjectExtensionPropertyInfo(
[NotNull] ObjectExtensionInfo objectExtension,
[NotNull] Type type,
[NotNull] string name)
{
ObjectExtension = Check.NotNull(objectExtension, nameof(objectExtension));
Type = Check.NotNull(type, nameof(type));
Name = Check.NotNull(name, nameof(name));
//ValidationAttributes = new List<ValidationAttribute>();
Configuration = new Dictionary<object, object>();
}
}

@ -37,7 +37,7 @@ namespace Volo.Abp.ObjectExtending
[Fact]
public void MapExtraPropertiesTo_Should_Only_Map_Source_Defined_Properties_If_Requested()
{
_person.MapExtraPropertiesTo(_personDto, MappingPropertyDefinitionCheck.Source);
_person.MapExtraPropertiesTo(_personDto, MappingPropertyDefinitionChecks.Source);
_personDto.GetProperty<string>("Name").ShouldBe("John"); //Defined in both classes
_personDto.GetProperty<int>("Age").ShouldBe(42); //Defined in source
@ -49,7 +49,7 @@ namespace Volo.Abp.ObjectExtending
[Fact]
public void MapExtraPropertiesTo_Should_Only_Map_Destination_Defined_Properties_If_Requested()
{
_person.MapExtraPropertiesTo(_personDto, MappingPropertyDefinitionCheck.Destination);
_person.MapExtraPropertiesTo(_personDto, MappingPropertyDefinitionChecks.Destination);
_personDto.GetProperty<string>("Name").ShouldBe("John"); //Defined in both classes
_personDto.GetProperty<int>("ChildCount").ShouldBe(2); //Defined in destination
@ -61,7 +61,7 @@ namespace Volo.Abp.ObjectExtending
[Fact]
public void MapExtraPropertiesTo_Should_Copy_all_With_No_Property_Definition_Check()
{
_person.MapExtraPropertiesTo(_personDto, MappingPropertyDefinitionCheck.None);
_person.MapExtraPropertiesTo(_personDto, MappingPropertyDefinitionChecks.None);
_personDto.GetProperty<string>("Name").ShouldBe("John");
_personDto.GetProperty<int>("Age").ShouldBe(42);

Loading…
Cancel
Save