From af42668f451a91b69c94e188152e3d09761b18d0 Mon Sep 17 00:00:00 2001
From: LordOf Xen <38406718+LordOfXen@users.noreply.github.com>
Date: Mon, 12 Apr 2021 16:17:03 -0700
Subject: [PATCH] Update BsonMapper.cs
Provides attribute flexibility for big projects where wrapping is a thing (e.g. wrapping the LiteDB to a library of the X project with custom attributes).
---
LiteDB/Client/Mapper/BsonMapper.cs | 92 ++++++++++++++++++++++++------
1 file changed, 76 insertions(+), 16 deletions(-)
diff --git a/LiteDB/Client/Mapper/BsonMapper.cs b/LiteDB/Client/Mapper/BsonMapper.cs
index 49335bbfe..9099f3e0c 100644
--- a/LiteDB/Client/Mapper/BsonMapper.cs
+++ b/LiteDB/Client/Mapper/BsonMapper.cs
@@ -234,6 +234,69 @@ internal EntityMapper GetEntityMapper(Type type)
return mapper;
}
+
+ ///
+ /// Override this function to customize the BsonIgnore attribute.
+ ///
+ /// The member info BsonIgnore attribute will be checked on.
+ /// Returns if the specified ignore attribute is defined on this member, otherwise .
+ protected virtual bool CheckIgnoreAttribute(MemberInfo mi)
+ {
+ // Check if the ignore attribute is set on the given member.
+ // Use the BsonIgnoreAttribute by default.
+ return CustomAttributeExtensions.IsDefined(mi, typeof(BsonIgnoreAttribute), true);
+ }
+
+ ///
+ /// Override this function to customize BsonField attribute.
+ ///
+ /// The member info BsonField attribute will be checked on.
+ /// Returns the name of the field if the attribute is set. Otherwise .
+ protected virtual string CheckFieldAttribute(MemberInfo mi)
+ {
+ // Check if the bson field attribute is set on the given member.
+ // Use the BsonFieldAttribute by default.
+ BsonFieldAttribute field = (BsonFieldAttribute)CustomAttributeExtensions.GetCustomAttributes(mi, typeof(BsonFieldAttribute), true).FirstOrDefault();
+ if (field != null && field.Name != null)
+ return field.Name;
+
+ return null;
+ }
+
+ ///
+ /// Override this function to customize BsonId attribute.
+ ///
+ /// The member info BsonId attribute will be checked on.
+ /// Returns the value of if set, otherwise .
+ protected virtual bool CheckIdAttribute(MemberInfo mi)
+ {
+ // Check if the bson id attribute is set on the given member.
+ // Use the BsonIdAttribute by default.
+ return ((BsonIdAttribute)CustomAttributeExtensions.GetCustomAttributes(mi, typeof(BsonIdAttribute), true).FirstOrDefault())?.AutoId ?? true;
+ }
+
+ ///
+ /// Override this function to customize BsonRef attribute.
+ ///
+ /// The member info BsonRef attribute will be checked on.
+ /// Gets whether the attribute was set on .
+ /// Returns the value of if set, otherwise .
+ protected virtual string CheckRefAttribute(MemberInfo mi, out bool found)
+ {
+ // Check if the bson ref attribute is set on the given member.
+ // Use the BsonRefAttribute by default.
+
+ // TODO: Consider wrapping the return value to a specific interface instead of requiring 'out'.
+ BsonRefAttribute attr =((BsonRefAttribute)CustomAttributeExtensions.GetCustomAttributes(mi, typeof(BsonRefAttribute), false).FirstOrDefault());
+ if (attr == null)
+ {
+ found = false;
+ return null;
+ }
+
+ found = true;
+ return attr.Collection;
+ }
///
/// Use this method to override how your class can be, by default, mapped from entity to Bson document.
@@ -253,20 +316,17 @@ protected virtual EntityMapper BuildEntityMapper(Type type)
foreach (var memberInfo in members)
{
- // checks [BsonIgnore]
- if (CustomAttributeExtensions.IsDefined(memberInfo, ignoreAttr, true)) continue;
+ // Check [BsonIgnore].
+ if (CheckIgnoreAttribute(memberInfo)) continue;
// checks field name conversion
var name = this.ResolveFieldName(memberInfo.Name);
// check if property has [BsonField]
- var field = (BsonFieldAttribute)CustomAttributeExtensions.GetCustomAttributes(memberInfo, fieldAttr, true).FirstOrDefault();
-
+ string fn = CheckFieldAttribute(memberInfo);
+
// check if property has [BsonField] with a custom field name
- if (field != null && field.Name != null)
- {
- name = field.Name;
- }
+ if (fn != null) name = fn;
// checks if memberInfo is id field
if (memberInfo == id)
@@ -279,7 +339,7 @@ protected virtual EntityMapper BuildEntityMapper(Type type)
var setter = Reflection.CreateGenericSetter(type, memberInfo);
// check if property has [BsonId] to get with was setted AutoId = true
- var autoId = (BsonIdAttribute)CustomAttributeExtensions.GetCustomAttributes(memberInfo, idAttr, true).FirstOrDefault();
+ bool autoId = CheckIdAttribute(memberInfo);
// get data type
var dataType = memberInfo is PropertyInfo ?
@@ -292,7 +352,7 @@ protected virtual EntityMapper BuildEntityMapper(Type type)
// create a property mapper
var member = new MemberMapper
{
- AutoId = autoId == null ? true : autoId.AutoId,
+ AutoId = autoId,
FieldName = name,
MemberName = memberInfo.Name,
DataType = dataType,
@@ -302,12 +362,12 @@ protected virtual EntityMapper BuildEntityMapper(Type type)
Setter = setter
};
- // check if property has [BsonRef]
- var dbRef = (BsonRefAttribute)CustomAttributeExtensions.GetCustomAttributes(memberInfo, dbrefAttr, false).FirstOrDefault();
+ // Check if property has [BsonRef].
+ string dbRef = CheckRefAttribute(memberInfo, out bool dbRefFound);
- if (dbRef != null && memberInfo is PropertyInfo)
+ if (dbRefFound && memberInfo is PropertyInfo)
{
- BsonMapper.RegisterDbRef(this, member, _typeNameBinder, dbRef.Collection ?? this.ResolveCollectionName((memberInfo as PropertyInfo).PropertyType));
+ BsonMapper.RegisterDbRef(this, member, _typeNameBinder, dbRef ?? this.ResolveCollectionName((memberInfo as PropertyInfo).PropertyType));
}
// support callback to user modify member mapper
@@ -322,7 +382,7 @@ protected virtual EntityMapper BuildEntityMapper(Type type)
return mapper;
}
-
+
///
/// Gets MemberInfo that refers to Id from a document object.
///
@@ -620,4 +680,4 @@ private static void RegisterDbRefList(BsonMapper mapper, MemberMapper member, IT
#endregion
}
-}
\ No newline at end of file
+}