diff --git a/framework/src/Volo.Abp.AutoMapper/AutoMapper/AbpAutoMapperExtensibleDtoExtensions.cs b/framework/src/Volo.Abp.AutoMapper/AutoMapper/AbpAutoMapperExtensibleDtoExtensions.cs index ab07f6235e..031a3a9948 100644 --- a/framework/src/Volo.Abp.AutoMapper/AutoMapper/AbpAutoMapperExtensibleDtoExtensions.cs +++ b/framework/src/Volo.Abp.AutoMapper/AutoMapper/AbpAutoMapperExtensibleDtoExtensions.cs @@ -8,7 +8,7 @@ namespace AutoMapper { public static IMappingExpression MapExtraProperties( this IMappingExpression mappingExpression, - MappingPropertyDefinitionCheck definitionCheck = MappingPropertyDefinitionCheck.Both) + MappingPropertyDefinitionChecks definitionChecks = MappingPropertyDefinitionChecks.Both) where TDestination : IHasExtraProperties where TSource : IHasExtraProperties { diff --git a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/Modeling/AbpEntityTypeBuilderExtensions.cs b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/Modeling/AbpEntityTypeBuilderExtensions.cs index b64866f8be..0a84b6871d 100644 --- a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/Modeling/AbpEntityTypeBuilderExtensions.cs +++ b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/Modeling/AbpEntityTypeBuilderExtensions.cs @@ -69,14 +69,17 @@ namespace Volo.Abp.EntityFrameworkCore.Modeling } public static void ConfigureObjectExtensions(this EntityTypeBuilder b) - where T : class + where T : class, IHasExtraProperties { b.As().TryConfigureObjectExtensions(); } public static void TryConfigureObjectExtensions(this EntityTypeBuilder b) { - ObjectExtensionManager.Instance.ConfigureEfCoreEntity(b); + if (b.Metadata.ClrType.IsAssignableTo()) + { + ObjectExtensionManager.Instance.ConfigureEfCoreEntity(b); + } } public static void ConfigureSoftDelete(this EntityTypeBuilder b) diff --git a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/HasExtraPropertiesObjectExtendingExtensions.cs b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/HasExtraPropertiesObjectExtendingExtensions.cs index 61ee13fc89..25156f298c 100644 --- a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/HasExtraPropertiesObjectExtendingExtensions.cs +++ b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/HasExtraPropertiesObjectExtendingExtensions.cs @@ -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 object. /// /// Checks property definitions (over the ) - /// based on the preference. + /// based on the preference. /// /// Source class type /// Destination class type /// The source object /// The destination object - /// + /// /// Controls which properties to map. /// public static void MapExtraPropertiesTo( - 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( + 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 object. /// /// Checks property definitions (over the ) - /// based on the preference. + /// based on the preference. /// /// Source class type (for definition check) /// Destination class type (for definition check) /// The source dictionary object /// The destination dictionary object - /// + /// /// Controls which properties to map. /// public static void MapExtraPropertiesTo( - Dictionary sourceDictionary, - Dictionary destinationDictionary, - MappingPropertyDefinitionCheck definitionCheck = MappingPropertyDefinitionCheck.Both) + [NotNull] Dictionary sourceDictionary, + [NotNull] Dictionary destinationDictionary, + MappingPropertyDefinitionChecks definitionChecks = MappingPropertyDefinitionChecks.Both) where TSource : IHasExtraProperties where TDestination : IHasExtraProperties { - var sourceObjectExtension = ObjectExtensionManager.Instance.GetOrNull(); - if (definitionCheck.HasFlag(MappingPropertyDefinitionCheck.Source) && + MapExtraPropertiesTo( + typeof(TSource), + typeof(TDestination), + sourceDictionary, + destinationDictionary, + definitionChecks + ); + } + + /// + /// Copies extra properties from the object + /// to the object. + /// + /// Checks property definitions (over the ) + /// based on the preference. + /// + /// Source type (for definition check) + /// Destination class type (for definition check) + /// The source dictionary object + /// The destination dictionary object + /// + /// Controls which properties to map. + /// + public static void MapExtraPropertiesTo( + [NotNull] Type sourceType, + [NotNull] Type destinationType, + [NotNull] Dictionary sourceDictionary, + [NotNull] Dictionary destinationDictionary, + MappingPropertyDefinitionChecks definitionChecks = MappingPropertyDefinitionChecks.Both) + { + Check.AssignableTo(sourceType, nameof(sourceType)); + Check.AssignableTo(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(); - 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!"); } } } diff --git a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/MappingPropertyDefinitionCheck.cs b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/MappingPropertyDefinitionChecks.cs similarity index 92% rename from framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/MappingPropertyDefinitionCheck.cs rename to framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/MappingPropertyDefinitionChecks.cs index f1bd9c3c66..b33638fa7c 100644 --- a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/MappingPropertyDefinitionCheck.cs +++ b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/MappingPropertyDefinitionChecks.cs @@ -3,7 +3,7 @@ namespace Volo.Abp.ObjectExtending { [Flags] - public enum MappingPropertyDefinitionCheck : byte + public enum MappingPropertyDefinitionChecks : byte { /// /// No check. Copy all extra properties from the source to the destination. diff --git a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ObjectExtensionInfo.cs b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ObjectExtensionInfo.cs index 6f59465660..14d527991f 100644 --- a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ObjectExtensionInfo.cs +++ b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ObjectExtensionInfo.cs @@ -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 Properties { get; } + [NotNull] public Dictionary Configuration { get; } - public ObjectExtensionInfo(Type type) + public ObjectExtensionInfo([NotNull] Type type) { - Type = type; + Type = Check.AssignableTo(type, nameof(type)); Properties = new Dictionary(); Configuration = new Dictionary(); } @@ -25,6 +29,7 @@ namespace Volo.Abp.ObjectExtending return Properties.ContainsKey(propertyName); } + [NotNull] public virtual ObjectExtensionInfo AddOrUpdateProperty( [NotNull] string propertyName, [CanBeNull] Action 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 GetProperties() { return Properties.Values.ToImmutableList(); diff --git a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ObjectExtensionManager.cs b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ObjectExtensionManager.cs index 0e94a3a984..cbc2aa3baa 100644 --- a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ObjectExtensionManager.cs +++ b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ObjectExtensionManager.cs @@ -16,6 +16,7 @@ namespace Volo.Abp.ObjectExtending ObjectsExtensions = new Dictionary(); } + [NotNull] public virtual ObjectExtensionManager AddOrUpdate( [CanBeNull] Action 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 configureAction = null) { - Check.NotNull(type, nameof(type)); - + Check.AssignableTo(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() + where TObject : IHasExtraProperties { return GetOrNull(typeof(TObject)); } + [CanBeNull] public virtual ObjectExtensionInfo GetOrNull([NotNull] Type type) { - Check.NotNull(type, nameof(type)); + Check.AssignableTo(type, nameof(type)); return ObjectsExtensions.GetOrDefault(type); } diff --git a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ObjectExtensionPropertyInfo.cs b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ObjectExtensionPropertyInfo.cs index ca08f0f03b..af5d0c2ce4 100644 --- a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ObjectExtensionPropertyInfo.cs +++ b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ObjectExtensionPropertyInfo.cs @@ -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 ValidationAttributes { get; } - [NotNull] public Dictionary 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(); Configuration = new Dictionary(); } } diff --git a/framework/test/Volo.Abp.ObjectExtending.Tests/Volo/Abp/ObjectExtending/HasExtraPropertiesObjectExtendingExtensions_Tests.cs b/framework/test/Volo.Abp.ObjectExtending.Tests/Volo/Abp/ObjectExtending/HasExtraPropertiesObjectExtendingExtensions_Tests.cs index 36d1f1988b..a51d9514b2 100644 --- a/framework/test/Volo.Abp.ObjectExtending.Tests/Volo/Abp/ObjectExtending/HasExtraPropertiesObjectExtendingExtensions_Tests.cs +++ b/framework/test/Volo.Abp.ObjectExtending.Tests/Volo/Abp/ObjectExtending/HasExtraPropertiesObjectExtendingExtensions_Tests.cs @@ -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("Name").ShouldBe("John"); //Defined in both classes _personDto.GetProperty("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("Name").ShouldBe("John"); //Defined in both classes _personDto.GetProperty("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("Name").ShouldBe("John"); _personDto.GetProperty("Age").ShouldBe(42);