[CSHARP-1154] Support for "Local" ConventionPack Overrides Created: 22/Dec/14  Updated: 09/Nov/22  Resolved: 09/Nov/22

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

Type: Improvement Priority: Major - P3
Reporter: Jaben Cargman Assignee: James Kovacs
Resolution: Won't Do Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Currently, there is no way to remove all conventions for a specific mapping. I'd like to be able to keep the global convention pack AS IS and than in the BsonClassMap remove or add specific conventions.



 Comments   
Comment by James Kovacs [ 09/Nov/22 ]

Issue closed as Won't Do since the desired behaviour can be implemented using the public API of ConventionRegistry. Thank you for providing your code demonstrating how to implement this.

Comment by Jaben Cargman [ 22/Dec/14 ]

In the interest of sharing if someone needs something similar, here is the code I wrote that does what I need:

public static class ConventionHelpers
    {
        /// <summary>
        /// The default convention pack.
        /// </summary>
        private const string DefaultConventionPackName = "__defaults__";
 
        /// <summary>
        /// The convention closure lookup.
        /// </summary>
        private static ConcurrentDictionary<string,Func<Type,bool>> _conventionClosureLookup = new ConcurrentDictionary<string, Func<Type, bool>>();
 
        /// <summary>
        /// A ConventionPack extension method that registers the exclusive convention pack.
        /// </summary>
        /// <param name="exclusivePack"> The exclusivePack to act on.</param>
        /// <param name="name">          The name.</param>
        /// <param name="typeFilter">    A filter specifying the type.</param>
        public static void RegisterExclusiveConventionPack(this ConventionPack exclusivePack, string name, Func<Type,bool> typeFilter)
        {
            _conventionClosureLookup.TryAdd(name, typeFilter);
 
            ConventionRegistry.Remove(DefaultConventionPackName);
            ConventionRegistry.Remove(name);
 
            var allFilterFunctions = _conventionClosureLookup.Values;
 
            // check for any exclusion function 
            ConventionRegistry.Register(
                DefaultConventionPackName,
                DefaultConventionPack.Instance,
                t =>
                    {
                        return allFilterFunctions.All(s => !s(t));
                    });
 
            ConventionRegistry.Register(name, exclusivePack, typeFilter);
        }
    }

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