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 +}