Browse Source

Resolved #3978: ObjectExtensionManager should automatically add RequiredAttribute & EnumDataTypeAttribute when needed

pull/3985/head
Halil İbrahim Kalkan 6 years ago
parent
commit
5f20c7726e
  1. 24
      framework/src/Volo.Abp.Core/Volo/Abp/Reflection/TypeHelper.cs
  2. 23
      framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ExtensionPropertyHelper.cs
  3. 2
      framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/Modularity/ExtensionPropertyConfiguration.cs
  4. 1
      framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/Modularity/ModuleExtensionConfigurationHelper.cs
  5. 3
      framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ObjectExtensionPropertyInfo.cs
  6. 7
      framework/test/Volo.Abp.Core.Tests/Volo/Abp/Reflection/TypeHelper_Tests.cs
  7. 74
      framework/test/Volo.Abp.ObjectExtending.Tests/Volo/Abp/ObjectExtending/ObjectExtensionManager_Tests.cs

24
framework/src/Volo.Abp.Core/Volo/Abp/Reflection/TypeHelper.cs

@ -10,6 +10,30 @@ namespace Volo.Abp.Reflection
{ {
public static class TypeHelper public static class TypeHelper
{ {
private static readonly HashSet<Type> NonNullablePrimitiveTypes = new HashSet<Type>
{
typeof(byte),
typeof(short),
typeof(int),
typeof(long),
typeof(sbyte),
typeof(ushort),
typeof(uint),
typeof(ulong),
typeof(bool),
typeof(float),
typeof(decimal),
typeof(DateTime),
typeof(DateTimeOffset),
typeof(TimeSpan),
typeof(Guid)
};
public static bool IsNonNullablePrimitiveType(Type type)
{
return NonNullablePrimitiveTypes.Contains(type);
}
public static bool IsFunc(object obj) public static bool IsFunc(object obj)
{ {
if (obj == null) if (obj == null)

23
framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ExtensionPropertyHelper.cs

@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using Volo.Abp.Reflection;
namespace Volo.Abp.ObjectExtending
{
public static class ExtensionPropertyHelper
{
public static IEnumerable<Attribute> GetDefaultAttributes(Type type)
{
if (TypeHelper.IsNonNullablePrimitiveType(type) || type.IsEnum)
{
yield return new RequiredAttribute();
}
if (type.IsEnum)
{
yield return new EnumDataTypeAttribute(type);
}
}
}
}

2
framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/Modularity/ExtensionPropertyConfiguration.cs

@ -61,6 +61,8 @@ namespace Volo.Abp.ObjectExtending.Modularity
Entity = new ExtensionPropertyEntityConfiguration(); Entity = new ExtensionPropertyEntityConfiguration();
UI = new ExtensionPropertyUiConfiguration(); UI = new ExtensionPropertyUiConfiguration();
Api = new ExtensionPropertyApiConfiguration(); Api = new ExtensionPropertyApiConfiguration();
Attributes.AddRange(ExtensionPropertyHelper.GetDefaultAttributes(Type));
} }
} }
} }

1
framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/Modularity/ModuleExtensionConfigurationHelper.cs

@ -148,6 +148,7 @@ namespace Volo.Abp.ObjectExtending.Modularity
propertyConfig.Name, propertyConfig.Name,
property => property =>
{ {
property.Attributes.Clear();
property.Attributes.AddRange(propertyConfig.Attributes); property.Attributes.AddRange(propertyConfig.Attributes);
property.DisplayName = propertyConfig.DisplayName; property.DisplayName = propertyConfig.DisplayName;
property.Validators.AddRange(propertyConfig.Validators); property.Validators.AddRange(propertyConfig.Validators);

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

@ -2,7 +2,6 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using JetBrains.Annotations; using JetBrains.Annotations;
using Microsoft.Extensions.Localization;
using Volo.Abp.Localization; using Volo.Abp.Localization;
namespace Volo.Abp.ObjectExtending namespace Volo.Abp.ObjectExtending
@ -61,6 +60,8 @@ namespace Volo.Abp.ObjectExtending
ValidationAttributes = new List<ValidationAttribute>(); ValidationAttributes = new List<ValidationAttribute>();
Attributes = new List<Attribute>(); Attributes = new List<Attribute>();
Validators = new List<Action<ObjectExtensionPropertyValidationContext>>(); Validators = new List<Action<ObjectExtensionPropertyValidationContext>>();
Attributes.AddRange(ExtensionPropertyHelper.GetDefaultAttributes(Type));
} }
} }
} }

7
framework/test/Volo.Abp.Core.Tests/Volo/Abp/Reflection/TypeHelper_Tests.cs

@ -7,6 +7,13 @@ namespace Volo.Abp.Reflection
{ {
public class TypeHelper_Tests public class TypeHelper_Tests
{ {
[Fact]
public void IsNonNullablePrimitiveType()
{
TypeHelper.IsNonNullablePrimitiveType(typeof(int)).ShouldBeTrue();
TypeHelper.IsNonNullablePrimitiveType(typeof(string)).ShouldBeFalse();
}
[Fact] [Fact]
public void Should_Generic_Type_From_Nullable() public void Should_Generic_Type_From_Nullable()
{ {

74
framework/test/Volo.Abp.ObjectExtending.Tests/Volo/Abp/ObjectExtending/ObjectExtensionManager_Tests.cs

@ -1,4 +1,5 @@
using System.Linq; using System.ComponentModel.DataAnnotations;
using System.Linq;
using Shouldly; using Shouldly;
using Xunit; using Xunit;
@ -22,7 +23,7 @@ namespace Volo.Abp.ObjectExtending
var objectExtension = _objectExtensionManager.GetOrNull<MyExtensibleObject>(); var objectExtension = _objectExtensionManager.GetOrNull<MyExtensibleObject>();
objectExtension.ShouldNotBeNull(); objectExtension.ShouldNotBeNull();
var properties = objectExtension.GetProperties(); var properties = objectExtension.GetProperties();
properties.Count.ShouldBe(1); properties.Count.ShouldBe(1);
properties.FirstOrDefault(p => p.Name == "TestProp").ShouldNotBeNull(); properties.FirstOrDefault(p => p.Name == "TestProp").ShouldNotBeNull();
@ -55,9 +56,78 @@ namespace Volo.Abp.ObjectExtending
property.Configuration["TestConfig2"].ShouldBe("TestConfig2-Value"); property.Configuration["TestConfig2"].ShouldBe("TestConfig2-Value");
} }
[Fact]
public void Should_Automatically_Add_RequiredAttribute_To_Non_Nullable_Types_And_Enums()
{
_objectExtensionManager
.AddOrUpdateProperty<MyExtensibleObject, int>("IntProp")
.AddOrUpdateProperty<MyExtensibleObject, bool>("BoolProp")
.AddOrUpdateProperty<MyExtensibleObject, int?>("NullableIntProp")
.AddOrUpdateProperty<MyExtensibleObject, string>("StringProp")
.AddOrUpdateProperty<MyExtensibleObject, MyTestEnum>("EnumProp");
_objectExtensionManager
.GetPropertyOrNull<MyExtensibleObject>("IntProp")
.Attributes
.ShouldContain(x => x is RequiredAttribute);
_objectExtensionManager
.GetPropertyOrNull<MyExtensibleObject>("BoolProp")
.Attributes
.ShouldContain(x => x is RequiredAttribute);
_objectExtensionManager
.GetPropertyOrNull<MyExtensibleObject>("EnumProp")
.Attributes
.ShouldContain(x => x is RequiredAttribute);
_objectExtensionManager
.GetPropertyOrNull<MyExtensibleObject>("NullableIntProp")
.Attributes
.ShouldNotContain(x => x is RequiredAttribute);
_objectExtensionManager
.GetPropertyOrNull<MyExtensibleObject>("StringProp")
.Attributes
.ShouldNotContain(x => x is RequiredAttribute);
}
[Fact]
public void Should_Automatically_Add_EnumDataTypeAttribute_For_Enums()
{
_objectExtensionManager
.AddOrUpdateProperty<MyExtensibleObject, MyTestEnum>("EnumProp");
_objectExtensionManager
.GetPropertyOrNull<MyExtensibleObject>("EnumProp")
.Attributes
.ShouldContain(x => x is EnumDataTypeAttribute);
}
[Fact]
public void Should_Be_Able_To_Clear_Auto_Added_Attributes()
{
_objectExtensionManager
.AddOrUpdateProperty<MyExtensibleObject, int>("IntProp", property =>
{
property.Attributes.Clear();
});
_objectExtensionManager
.GetPropertyOrNull<MyExtensibleObject>("IntProp")
.Attributes
.ShouldNotContain(x => x is RequiredAttribute);
}
private class MyExtensibleObject : ExtensibleObject private class MyExtensibleObject : ExtensibleObject
{ {
} }
private enum MyTestEnum
{
EnumValue1,
EnumValue2,
}
} }
} }

Loading…
Cancel
Save