Skip to content

Commit 8b15445

Browse files
committed
Added convention registry
1 parent 9011589 commit 8b15445

File tree

5 files changed

+173
-97
lines changed

5 files changed

+173
-97
lines changed

src/MongoDB.Bson/Serialization/BsonSerializationDomain.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ internal class BsonSerializationDomain : IBsonSerializationDomainInternal, IDisp
2020
// private fields
2121
private ReaderWriterLockSlim _configLock = new(LockRecursionPolicy.SupportsRecursion);
2222
private IBsonClassMapDomain _classMapDomain;
23+
private IConventionRegistryDomain _conventionRegistryDomain;
2324
private Dictionary<Type, IIdGenerator> _idGenerators = new();
2425
private Dictionary<Type, IDiscriminatorConvention> _discriminatorConventions = new();
2526
private Dictionary<BsonValue, HashSet<Type>> _discriminators = new();
@@ -39,6 +40,7 @@ internal class BsonSerializationDomain : IBsonSerializationDomainInternal, IDisp
3940
CreateSerializerRegistry();
4041
RegisterIdGenerators();
4142
_classMapDomain = new BsonClassMapDomain();
43+
_conventionRegistryDomain = new ConventionRegistryDomain();
4244
Name = name ?? "CUSTOM"; //TODO remove after testing is done
4345
}
4446

@@ -734,6 +736,8 @@ public void Serialize(
734736

735737
public IBsonClassMapDomain BsonClassMap => _classMapDomain;
736738

739+
public IConventionRegistryDomain ConventionRegistry => _conventionRegistryDomain;
740+
737741
/// <summary>
738742
/// Tries to register a serializer for a type.
739743
/// </summary>

src/MongoDB.Bson/Serialization/Conventions/ConventionRegistry.cs

Lines changed: 7 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -14,103 +14,31 @@
1414
*/
1515

1616
using System;
17-
using System.Collections.Generic;
1817

1918
namespace MongoDB.Bson.Serialization.Conventions
2019
{
2120
/// <summary>
2221
/// Represents a registry of conventions.
2322
/// </summary>
24-
public static class ConventionRegistry //TODO Probably this should get the same treatment as BsonSerializer....
23+
public static class ConventionRegistry
2524
{
26-
// private static fields
27-
private readonly static List<ConventionPackContainer> __conventionPacks = new List<ConventionPackContainer>();
28-
private readonly static object __lock = new object();
29-
30-
// static constructors
31-
static ConventionRegistry()
32-
{
33-
Register("__defaults__", DefaultConventionPack.Instance, t => true);
34-
Register("__attributes__", AttributeConventionPack.Instance, t => true);
35-
}
36-
3725
// public static methods
3826
/// <summary>
3927
/// Looks up the effective set of conventions that apply to a type.
4028
/// </summary>
4129
/// <param name="type">The type.</param>
4230
/// <returns>The conventions for that type.</returns>
43-
public static IConventionPack Lookup(Type type)
44-
{
45-
if (type == null)
46-
{
47-
throw new ArgumentNullException("type");
48-
}
49-
50-
lock (__lock)
51-
{
52-
var pack = new ConventionPack();
53-
54-
// append any attribute packs (usually just one) at the end so attributes are processed last
55-
var attributePacks = new List<IConventionPack>();
56-
foreach (var container in __conventionPacks)
57-
{
58-
if (container.Filter(type))
59-
{
60-
61-
if (container.Name == "__attributes__")
62-
{
63-
attributePacks.Add(container.Pack);
64-
}
65-
else
66-
{
67-
pack.Append(container.Pack);
68-
}
69-
}
70-
}
71-
72-
foreach (var attributePack in attributePacks)
73-
{
74-
pack.Append(attributePack);
75-
}
76-
77-
return pack;
78-
}
79-
}
31+
public static IConventionPack Lookup(Type type) =>
32+
BsonSerializer.DefaultSerializationDomain.ConventionRegistry.Lookup(type);
8033

8134
/// <summary>
8235
/// Registers the conventions.
8336
/// </summary>
8437
/// <param name="name">The name.</param>
8538
/// <param name="conventions">The conventions.</param>
8639
/// <param name="filter">The filter.</param>
87-
public static void Register(string name, IConventionPack conventions, Func<Type, bool> filter)
88-
{
89-
if (name == null)
90-
{
91-
throw new ArgumentNullException("name");
92-
}
93-
if (conventions == null)
94-
{
95-
throw new ArgumentNullException("conventions");
96-
}
97-
if (filter == null)
98-
{
99-
throw new ArgumentNullException("filter");
100-
}
101-
102-
lock (__lock)
103-
{
104-
var container = new ConventionPackContainer
105-
{
106-
Filter = filter,
107-
Name = name,
108-
Pack = conventions
109-
};
110-
111-
__conventionPacks.Add(container);
112-
}
113-
}
40+
public static void Register(string name, IConventionPack conventions, Func<Type, bool> filter) =>
41+
BsonSerializer.DefaultSerializationDomain.ConventionRegistry.Register(name, conventions, filter);
11442

11543
/// <summary>
11644
/// Removes the conventions specified by the given name.
@@ -119,25 +47,7 @@ public static void Register(string name, IConventionPack conventions, Func<Type,
11947
/// <remarks>Removing a convention allows the removal of the special __defaults__ conventions
12048
/// and the __attributes__ conventions for those who want to completely customize the
12149
/// experience.</remarks>
122-
public static void Remove(string name)
123-
{
124-
if (name == null)
125-
{
126-
throw new ArgumentNullException("name");
127-
}
128-
129-
lock (__lock)
130-
{
131-
__conventionPacks.RemoveAll(x => x.Name == name);
132-
}
133-
}
134-
135-
// private class
136-
private class ConventionPackContainer
137-
{
138-
public Func<Type, bool> Filter;
139-
public string Name;
140-
public IConventionPack Pack;
141-
}
50+
public static void Remove(string name) =>
51+
BsonSerializer.DefaultSerializationDomain.ConventionRegistry.Remove(name);
14252
}
14353
}
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
using System;
2+
using System.Collections.Generic;
3+
4+
namespace MongoDB.Bson.Serialization.Conventions
5+
{
6+
internal class ConventionRegistryDomain : IConventionRegistryDomain
7+
{
8+
private readonly List<ConventionPackContainer> _conventionPacks = [];
9+
private readonly object _lock = new();
10+
11+
// constructors
12+
internal ConventionRegistryDomain()
13+
{
14+
Register("__defaults__", DefaultConventionPack.Instance, t => true);
15+
Register("__attributes__", AttributeConventionPack.Instance, t => true);
16+
}
17+
18+
// public static methods
19+
/// <summary>
20+
/// Looks up the effective set of conventions that apply to a type.
21+
/// </summary>
22+
/// <param name="type">The type.</param>
23+
/// <returns>The conventions for that type.</returns>
24+
public IConventionPack Lookup(Type type)
25+
{
26+
if (type == null)
27+
{
28+
throw new ArgumentNullException("type");
29+
}
30+
31+
lock (_lock)
32+
{
33+
var pack = new ConventionPack();
34+
35+
// append any attribute packs (usually just one) at the end so attributes are processed last
36+
var attributePacks = new List<IConventionPack>();
37+
foreach (var container in _conventionPacks)
38+
{
39+
if (container.Filter(type))
40+
{
41+
42+
if (container.Name == "__attributes__")
43+
{
44+
attributePacks.Add(container.Pack);
45+
}
46+
else
47+
{
48+
pack.Append(container.Pack);
49+
}
50+
}
51+
}
52+
53+
foreach (var attributePack in attributePacks)
54+
{
55+
pack.Append(attributePack);
56+
}
57+
58+
return pack;
59+
}
60+
}
61+
62+
/// <summary>
63+
/// Registers the conventions.
64+
/// </summary>
65+
/// <param name="name">The name.</param>
66+
/// <param name="conventions">The conventions.</param>
67+
/// <param name="filter">The filter.</param>
68+
public void Register(string name, IConventionPack conventions, Func<Type, bool> filter)
69+
{
70+
if (name == null)
71+
{
72+
throw new ArgumentNullException("name");
73+
}
74+
75+
if (conventions == null)
76+
{
77+
throw new ArgumentNullException("conventions");
78+
}
79+
80+
if (filter == null)
81+
{
82+
throw new ArgumentNullException("filter");
83+
}
84+
85+
lock (_lock)
86+
{
87+
var container = new ConventionPackContainer
88+
{
89+
Filter = filter,
90+
Name = name,
91+
Pack = conventions
92+
};
93+
94+
_conventionPacks.Add(container);
95+
}
96+
}
97+
98+
/// <summary>
99+
/// Removes the conventions specified by the given name.
100+
/// </summary>
101+
/// <param name="name">The name.</param>
102+
/// <remarks>Removing a convention allows the removal of the special __defaults__ conventions
103+
/// and the __attributes__ conventions for those who want to completely customize the
104+
/// experience.</remarks>
105+
public void Remove(string name)
106+
{
107+
if (name == null)
108+
{
109+
throw new ArgumentNullException("name");
110+
}
111+
112+
lock (_lock)
113+
{
114+
_conventionPacks.RemoveAll(x => x.Name == name);
115+
}
116+
}
117+
118+
// private class
119+
private class ConventionPackContainer
120+
{
121+
public Func<Type, bool> Filter;
122+
public string Name;
123+
public IConventionPack Pack;
124+
}
125+
}
126+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
using System;
2+
3+
namespace MongoDB.Bson.Serialization.Conventions
4+
{
5+
/// <summary>
6+
/// //TODO
7+
/// </summary>
8+
public interface IConventionRegistryDomain
9+
{
10+
/// <summary>
11+
/// //TODO
12+
/// </summary>
13+
/// <param name="type"></param>
14+
/// <returns></returns>
15+
IConventionPack Lookup(Type type);
16+
17+
/// <summary>
18+
/// //TODO
19+
/// </summary>
20+
/// <param name="name"></param>
21+
/// <param name="conventions"></param>
22+
/// <param name="filter"></param>
23+
void Register(string name, IConventionPack conventions, Func<Type, bool> filter);
24+
25+
/// <summary>
26+
/// //TODO
27+
/// </summary>
28+
/// <param name="name"></param>
29+
void Remove(string name);
30+
}
31+
}

src/MongoDB.Bson/Serialization/IBsonSerializationDomain.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,11 @@ void Serialize(
288288
/// //TODO
289289
/// </summary>
290290
IBsonClassMapDomain BsonClassMap { get; }
291+
292+
/// <summary>
293+
/// //TODO
294+
/// </summary>
295+
IConventionRegistryDomain ConventionRegistry { get; }
291296
}
292297

293298
internal interface IBsonSerializationDomainInternal : IBsonSerializationDomain

0 commit comments

Comments
 (0)