[CSHARP-369] BsonIgnoreExtraElementsAttribute inheritable? Created: 20/Dec/11  Updated: 02/Apr/15  Resolved: 29/Dec/11

Status: Closed
Project: C# Driver
Component/s: None
Affects Version/s: 1.3.1
Fix Version/s: 1.4

Type: Improvement Priority: Trivial - P5
Reporter: Rob Janssen Assignee: Robert Stam
Resolution: Done Votes: 0
Labels: serialization
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Attachments: Text File BsonIgnoreExtraElementsAttribute.cs    
Backwards Compatibility: Fully Compatible

 Description   

BsonIgnoreExtraElementsAttribute
Could you consider adding the inherited option? I realize this might break older code if I understand correctly. In that case could you consider adding a new "BsonIgnoreExtraElementsAttributeInherited" (or something) attribute which is exactly the same but with the inherited = true option.

Maybe I'm on the wrong track tough, would love feedback on this.

My problem is that I am creating a repository on which all entities inherit from the Entity class; for my use-case it would be preferable to have all entities ignore extra elements when present and I don't like adding the BsonIgnoreExtraElementsAttribute to each and every entity.

I also tried inheriting from the BsonIgnoreExtraElementsAttribute e.g. "MyIgnore") and although it worked on the class I applied the "MyIgnore" attribute to, the inherited classes didn't ignore extra elements even though the MyIgnore had the inherited option set to true.

Again, I might be on the wrong track here; please correct me if I'm wrong.



 Comments   
Comment by Robert Stam [ 30/Dec/11 ]

Thanks for the suggestion.

Comment by Rob Janssen [ 30/Dec/11 ]

Awesome and even better than my suggestion indeed! Thanks!

Comment by Robert Stam [ 29/Dec/11 ]

Implemented slightly differently. Use:

[BsonIgnoreExtraElements(Inherited = true)]

Constructors with multiple boolean parameters are confusing since it's easy to forget which boolean does what.

Comment by Robert Stam [ 23/Dec/11 ]

Seems reasonable.

IgnoreExtraElements is a property of BsonClassMap. Since class maps can be created in any order (base classes before derived classes or vice versa) the actual flowing down of the inherited value from base class to derived classes would have to happen in Freeze (similar to how DiscriminatorIsRequired is inherited except that it would be conditional).

Comment by Rob Janssen [ 22/Dec/11 ]

After some thought I agree; adding a constructor-parameter to the BsonIgnoreExtraElementsAttribute that specifies inherited and defaults to false it wouldn't break any existing code.

I took a minute and whipped up the required changes to be made (I guess) to the BsonIgnoreExtraElementsAttribute class:

BsonIgnoreExtraElementsAttribute.cs

/* Copyright 2010-2011 10gen Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace MongoDB.Bson.Serialization.Attributes
{
    /// <summary>
    /// Specifies whether extra elements should be ignored when this class is deserialized.
    /// </summary>
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct)]
    public class BsonIgnoreExtraElementsAttribute : Attribute
    {
        // private fields
        private bool ignoreExtraElements;
        private bool inherited;
 
        // constructors
        /// <summary>
        /// Initializes a new instance of the BsonIgnoreExtraElementsAttribute class.
        /// </summary>
        public BsonIgnoreExtraElementsAttribute()
            : this(true, false)
        {
        }
 
        /// <summary>
        /// Initializes a new instance of the BsonIgnoreExtraElementsAttribute class.
        /// </summary>
        /// <param name="ignoreExtraElements">Whether extra elements should be ignored when this class is deserialized.</param>
        public BsonIgnoreExtraElementsAttribute(bool ignoreExtraElements)
            : this(ignoreExtraElements, false)
        {
        }
 
        /// <summary>
        /// Initializes a new instance of the BsonIgnoreExtraElementsAttribute class.
        /// </summary>
        /// <param name="ignoreExtraElements">Whether extra elements should be ignored when this class is deserialized.</param>
        /// <param name="inherited">Whether derived classes inherit this attribute.</param>
        public BsonIgnoreExtraElementsAttribute(bool ignoreExtraElements, bool inherited)
        {
            this.ignoreExtraElements = ignoreExtraElements;
            this.inherited = inherited;
        }
 
        // public properties
        /// <summary>
        /// Gets whether extra elements should be ignored when this class is deserialized.
        /// </summary>
        public bool IgnoreExtraElements
        {
            get { return ignoreExtraElements; }
        }
 
        // public properties
        /// <summary>
        /// Gets whether derived classes inherit this attribute.
        /// </summary>
        public bool Inherited
        {
            get { return inherited; }
        }
    }
}

(Also attached to this issue for your convenience)

Usage example:

Example.cs

    //Usage example
    [BsonIgnoreExtraElements(true,true)]
    public class Entity
    {
    }
 
    public class Customer : Entity
    {
        //Should now also ignore extra elements
    }

The actual handling of the inheritance should be done, I guess, around here somewhere. I haven't had the time yet to look into that but will as soon as I can.

Thanks for your input so far!

Comment by Craig Wilson [ 21/Dec/11 ]

Doesn't seem like this would break existing code. It would default to false unless otherwise specified, so existing implementations would still be exactly the same.

Generated at Wed Feb 07 21:36:37 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.