diff --git a/framework/src/Volo.Abp.Core/System/AbpTypeExtensions.cs b/framework/src/Volo.Abp.Core/System/AbpTypeExtensions.cs
index a90e4212e1..a930096404 100644
--- a/framework/src/Volo.Abp.Core/System/AbpTypeExtensions.cs
+++ b/framework/src/Volo.Abp.Core/System/AbpTypeExtensions.cs
@@ -1,4 +1,7 @@
-namespace System
+using System.Collections.Generic;
+using JetBrains.Annotations;
+
+namespace System
{
public static class AbpTypeExtensions
{
@@ -31,5 +34,36 @@
{
return targetType.IsAssignableFrom(type);
}
+
+ ///
+ /// Gets all base classes of this type.
+ ///
+ /// The type to get its base classes.
+ /// True, to include the standard type in the returned array.
+ public static Type[] GetBaseClasses(this Type type, bool includeObject = true)
+ {
+ var types = new List();
+ AddTypeAndBaseTypesRecursively(types, type.BaseType, includeObject);
+ return types.ToArray();
+ }
+
+ private static void AddTypeAndBaseTypesRecursively(
+ [NotNull] List types,
+ [CanBeNull] Type type,
+ bool includeObject)
+ {
+ if (type == null)
+ {
+ return;
+ }
+
+ if (!includeObject && type == typeof(object))
+ {
+ return;
+ }
+
+ AddTypeAndBaseTypesRecursively(types, type.BaseType, includeObject);
+ types.Add(type);
+ }
}
}
diff --git a/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/AbpBsonClassMapExtensions.cs b/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/AbpBsonClassMapExtensions.cs
index f53e524914..a450a4bc43 100644
--- a/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/AbpBsonClassMapExtensions.cs
+++ b/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/AbpBsonClassMapExtensions.cs
@@ -1,4 +1,5 @@
using System;
+using System.Reflection;
using MongoDB.Bson.Serialization;
using Volo.Abp.Data;
@@ -9,34 +10,50 @@ namespace Volo.Abp.MongoDB
public static void ConfigureAbpConventions(this BsonClassMap map)
{
map.AutoMap();
- map.ConfigureExtraProperties();
+ map.TryConfigureExtraProperties();
}
- public static void ConfigureExtraProperties(this BsonClassMap map)
+ public static bool TryConfigureExtraProperties(this BsonClassMap map)
where TEntity : class, IHasExtraProperties
{
+ var property = map.ClassType.GetProperty(
+ nameof(IHasExtraProperties.ExtraProperties),
+ BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty
+ );
+
+ if (property?.DeclaringType != map.ClassType)
+ {
+ return false;
+ }
+
map.SetExtraElementsMember(new BsonMemberMap(
map,
typeof(TEntity).GetMember(nameof(IHasExtraProperties.ExtraProperties))[0])
);
+
+ return true;
}
- ///
- /// Configures SetExtraElementsMember if the
- /// implements the interface.
- /// Otherwise, does nothing
- ///
- public static void ConfigureExtraProperties(this BsonClassMap map)
+ public static bool TryConfigureExtraProperties(this BsonClassMap map)
{
- if (map.ClassType.IsAssignableTo())
+ if (!map.ClassType.IsAssignableTo())
{
- map.SetExtraElementsMember(
- new BsonMemberMap(
- map,
- map.ClassType.GetMember(nameof(IHasExtraProperties.ExtraProperties))[0]
- )
- );
+ return false;
}
+
+ var property = map.ClassType.GetProperty(
+ nameof(IHasExtraProperties.ExtraProperties),
+ BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty
+ );
+
+ if (property?.DeclaringType != map.ClassType)
+ {
+ return false;
+ }
+
+ map.MapExtraElementsMember(property);
+
+ return true;
}
}
}
diff --git a/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/MongoModelBuilder.cs b/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/MongoModelBuilder.cs
index 788d0bdbea..43ffbabf4a 100644
--- a/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/MongoModelBuilder.cs
+++ b/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/MongoModelBuilder.cs
@@ -3,6 +3,7 @@ using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
+using Volo.Abp.Domain.Entities;
namespace Volo.Abp.MongoDB
{
@@ -19,24 +20,40 @@ namespace Volo.Abp.MongoDB
public MongoDbContextModel Build()
{
- var entityModels = _entityModelBuilders
- .Select(x => x.Value)
- .Cast()
- .ToImmutableDictionary(x => x.EntityType, x => x);
-
- foreach (var entityModel in entityModels.Values)
+ lock (SyncObj)
{
- var map = entityModel.As().GetMap();
- lock (SyncObj)
+ var entityModels = _entityModelBuilders
+ .Select(x => x.Value)
+ .Cast()
+ .ToImmutableDictionary(x => x.EntityType, x => x);
+
+ var baseClasses = new List();
+
+ foreach (var entityModel in entityModels.Values)
{
+ var map = entityModel.As().GetMap();
if (!BsonClassMap.IsClassMapRegistered(map.ClassType))
{
BsonClassMap.RegisterClassMap(map);
}
+
+ baseClasses.AddRange(entityModel.EntityType.GetBaseClasses(includeObject: false));
}
- }
- return new MongoDbContextModel(entityModels);
+ baseClasses = baseClasses.Distinct().ToList();
+
+ foreach (var baseClass in baseClasses)
+ {
+ if (!BsonClassMap.IsClassMapRegistered(baseClass))
+ {
+ var map = new BsonClassMap(baseClass);
+ map.ConfigureAbpConventions();
+ BsonClassMap.RegisterClassMap(map);
+ }
+ }
+
+ return new MongoDbContextModel(entityModels);
+ }
}
public virtual void Entity(Action> buildAction = null)
diff --git a/framework/test/Volo.Abp.Core.Tests/System/AbpTypeExtensions_Tests.cs b/framework/test/Volo.Abp.Core.Tests/System/AbpTypeExtensions_Tests.cs
new file mode 100644
index 0000000000..382440a3f4
--- /dev/null
+++ b/framework/test/Volo.Abp.Core.Tests/System/AbpTypeExtensions_Tests.cs
@@ -0,0 +1,32 @@
+using Shouldly;
+using Xunit;
+
+namespace System
+{
+ public class AbpTypeExtensions_Tests
+ {
+ [Fact]
+ public void GetBaseClasses()
+ {
+ var baseClasses = typeof(MyClass).GetBaseClasses(includeObject: false);
+ baseClasses.Length.ShouldBe(2);
+ baseClasses[0].ShouldBe(typeof(MyBaseClass1));
+ baseClasses[1].ShouldBe(typeof(MyBaseClass2));
+ }
+
+ public abstract class MyBaseClass1
+ {
+
+ }
+
+ public class MyBaseClass2 : MyBaseClass1
+ {
+
+ }
+
+ public class MyClass : MyBaseClass2
+ {
+
+ }
+ }
+}