From 55016d84462ef26c30f8a20f637699c0a014a4f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Sun, 26 Apr 2020 00:21:43 +0300 Subject: [PATCH] ExtensibleObject should set default values for defined properties. --- .../Volo/Abp/Reflection/TypeHelper.cs | 15 ++++++++ .../Volo/Abp/Domain/Entities/AggregateRoot.cs | 9 +++-- .../Abp/Data/HasExtraPropertiesExtensions.cs | 30 +++++++++++++++ .../Abp/ObjectExtending/ExtensibleObject.cs | 12 ++++++ .../ObjectExtending/ExtensibleObject_Tests.cs | 37 +++++++++++++++++++ .../TestObjects/ExtensibleTestPerson.cs | 9 +++++ 6 files changed, 109 insertions(+), 3 deletions(-) create mode 100644 framework/test/Volo.Abp.ObjectExtending.Tests/Volo/Abp/ObjectExtending/ExtensibleObject_Tests.cs diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Reflection/TypeHelper.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Reflection/TypeHelper.cs index 5f66f4788e..eeb0259321 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/Reflection/TypeHelper.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Reflection/TypeHelper.cs @@ -131,5 +131,20 @@ namespace Volo.Abp.Reflection type == typeof(TimeSpan) || type == typeof(Guid); } + + public static object GetDefaultValue() + { + return GetDefaultValue(typeof(T)); + } + + public static object GetDefaultValue(Type type) + { + if (type.IsValueType) + { + return Activator.CreateInstance(type); + } + + return null; + } } } diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/AggregateRoot.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/AggregateRoot.cs index be02f3d398..b0c20131ef 100644 --- a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/AggregateRoot.cs +++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/AggregateRoot.cs @@ -25,8 +25,9 @@ namespace Volo.Abp.Domain.Entities protected AggregateRoot() { - ExtraProperties = new Dictionary(); ConcurrencyStamp = Guid.NewGuid().ToString("N"); + ExtraProperties = new Dictionary(); + this.SetDefaultsForExtraProperties(); } protected virtual void AddLocalEvent(object eventData) @@ -85,15 +86,17 @@ namespace Volo.Abp.Domain.Entities protected AggregateRoot() { - ExtraProperties = new Dictionary(); ConcurrencyStamp = Guid.NewGuid().ToString("N"); + ExtraProperties = new Dictionary(); + this.SetDefaultsForExtraProperties(); } protected AggregateRoot(TKey id) : base(id) { - ExtraProperties = new Dictionary(); ConcurrencyStamp = Guid.NewGuid().ToString("N"); + ExtraProperties = new Dictionary(); + this.SetDefaultsForExtraProperties(); } protected virtual void AddLocalEvent(object eventData) diff --git a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/Data/HasExtraPropertiesExtensions.cs b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/Data/HasExtraPropertiesExtensions.cs index 2b75e5fc8f..febf95bd22 100644 --- a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/Data/HasExtraPropertiesExtensions.cs +++ b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/Data/HasExtraPropertiesExtensions.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Globalization; +using Volo.Abp.ObjectExtending; using Volo.Abp.Reflection; namespace Volo.Abp.Data @@ -49,5 +50,34 @@ namespace Volo.Abp.Data source.ExtraProperties.Remove(name); return source; } + + public static TSource SetDefaultsForExtraProperties(this TSource source, Type objectType = null) + where TSource : IHasExtraProperties + { + var properties = ObjectExtensionManager.Instance + .GetProperties(objectType ?? typeof(TSource)); + + foreach (var property in properties) + { + if (source.HasProperty(property.Name)) + { + continue; + } + + source.ExtraProperties[property.Name] = TypeHelper.GetDefaultValue(property.Type); + } + + return source; + } + + public static void SetDefaultsForExtraProperties(object source, Type objectType) + { + if (!(source is IHasExtraProperties)) + { + throw new ArgumentException($"Given {nameof(source)} object does not implement the {nameof(IHasExtraProperties)} interface!", nameof(source)); + } + + ((IHasExtraProperties) source).SetDefaultsForExtraProperties(objectType); + } } } \ No newline at end of file diff --git a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ExtensibleObject.cs b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ExtensibleObject.cs index c9c601fce9..d83efac53f 100644 --- a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ExtensibleObject.cs +++ b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ExtensibleObject.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using Volo.Abp.Data; +using Volo.Abp.DynamicProxy; namespace Volo.Abp.ObjectExtending { @@ -11,8 +12,19 @@ namespace Volo.Abp.ObjectExtending public Dictionary ExtraProperties { get; protected set; } public ExtensibleObject() + : this(true) + { + + } + + public ExtensibleObject(bool setDefaultsForExtraProperties) { ExtraProperties = new Dictionary(); + + if (setDefaultsForExtraProperties) + { + this.SetDefaultsForExtraProperties(ProxyHelper.UnProxy(this).GetType()); + } } public virtual IEnumerable Validate(ValidationContext validationContext) diff --git a/framework/test/Volo.Abp.ObjectExtending.Tests/Volo/Abp/ObjectExtending/ExtensibleObject_Tests.cs b/framework/test/Volo.Abp.ObjectExtending.Tests/Volo/Abp/ObjectExtending/ExtensibleObject_Tests.cs new file mode 100644 index 0000000000..fdd7f600f6 --- /dev/null +++ b/framework/test/Volo.Abp.ObjectExtending.Tests/Volo/Abp/ObjectExtending/ExtensibleObject_Tests.cs @@ -0,0 +1,37 @@ +using Shouldly; +using Volo.Abp.Data; +using Volo.Abp.ObjectExtending.TestObjects; +using Xunit; + +namespace Volo.Abp.ObjectExtending +{ + public class ExtensibleObject_Tests : AbpObjectExtendingTestBase + { + [Fact] + public void Should_Set_Default_Values_For_Defined_Properties_On_Create() + { + var person = new ExtensibleTestPerson(); + + person.HasProperty("Name").ShouldBeTrue(); + person.HasProperty("Age").ShouldBeTrue(); + person.HasProperty("NoPairCheck").ShouldBeTrue(); + person.HasProperty("CityName").ShouldBeTrue(); + + person.GetProperty("Name").ShouldBeNull(); + person.GetProperty("Age").ShouldBe(0); + person.GetProperty("NoPairCheck").ShouldBeNull(); + person.GetProperty("CityName").ShouldBeNull(); + } + + [Fact] + public void Should_Not_Set_Default_Values_For_Defined_Properties_If_Requested() + { + var person = new ExtensibleTestPerson(false); + + person.HasProperty("Name").ShouldBeFalse(); + person.HasProperty("Age").ShouldBeFalse(); + person.HasProperty("NoPairCheck").ShouldBeFalse(); + person.HasProperty("CityName").ShouldBeFalse(); + } + } +} diff --git a/framework/test/Volo.Abp.ObjectExtending.Tests/Volo/Abp/ObjectExtending/TestObjects/ExtensibleTestPerson.cs b/framework/test/Volo.Abp.ObjectExtending.Tests/Volo/Abp/ObjectExtending/TestObjects/ExtensibleTestPerson.cs index bd24209212..25bce6e45a 100644 --- a/framework/test/Volo.Abp.ObjectExtending.Tests/Volo/Abp/ObjectExtending/TestObjects/ExtensibleTestPerson.cs +++ b/framework/test/Volo.Abp.ObjectExtending.Tests/Volo/Abp/ObjectExtending/TestObjects/ExtensibleTestPerson.cs @@ -2,6 +2,15 @@ { public class ExtensibleTestPerson : ExtensibleObject { + public ExtensibleTestPerson() + { + } + + public ExtensibleTestPerson(bool setDefaultsForExtraProperties) + : base(setDefaultsForExtraProperties) + { + + } } }