-
Notifications
You must be signed in to change notification settings - Fork 1.3k
/
Copy pathForceAsBsonClassMapSerializationProvider.cs
89 lines (81 loc) · 3.97 KB
/
ForceAsBsonClassMapSerializationProvider.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
namespace MongoDB.Bson.Serialization
{
using System;
using System.Collections.Generic;
using System.Linq;
/// <summary>
/// Represents a BSON serialization provider which defines that some serializable types should be treated
/// as BSON class maps.
/// </summary>
/// <remarks>
/// Argumented types to be forced as BSON class maps can be either concrete or also base class and interface ones.
///
/// This serialization provider is useful when a class may implement a collection interface (for example, <see cref="System.Collections.Generic.IList{T}"/>)
/// because the domain requires the class to act as a collection, but in terms of serialization, it must be serialized as a regular
/// POCO class.
/// </remarks>
/// <example>
/// For example, given the following class:
///
/// <code language="c#">
/// public interface ISomeInterface { }
/// public class SomeImpl : ISomeInterface { }
/// </code>
///
/// This provider can be configured both to force any <codeInline>SomeImpl</codeInline> to be treated as
/// BSON class map and also any implementation of <codeInline>ISomeInterface</codeInline> can be configured as a
/// forced type to let any implementation be serialized as a BSON class map:
///
/// <code language="c#">
/// ForceAsBsonClassMapSerializationProvider provider = new ForceAsBsonClassMapSerializationProvider(typeof(SomeImpl));
///
/// // or
///
/// ForceAsBsonClassMapSerializationProvider provider = new ForceAsBsonClassMapSerializationProvider(typeof(ISomeInterface));
///
/// // or even both
///
/// ForceAsBsonClassMapSerializationProvider provider = new ForceAsBsonClassMapSerializationProvider(typeof(SomeImpl), typeof(ISomeInterface));
/// </code>
/// </example>
public sealed class ForceAsBsonClassMapSerializationProvider : BsonSerializationProviderBase
{
private readonly HashSet<Type> _forcedTypes;
/// <summary>
/// Constructor to give forced types as a type array.
/// </summary>
/// <param name="forcedTypes">The whole types to be forced as BSON class maps</param>
public ForceAsBsonClassMapSerializationProvider(params Type[] forcedTypes)
: this((IEnumerable<Type>)forcedTypes)
{
}
/// <summary>
/// Constructor to give forced types as a sequence of types.
/// </summary>
/// <param name="forcedTypes">The whole types to be forced as BSON class maps</param>
public ForceAsBsonClassMapSerializationProvider(IEnumerable<Type> forcedTypes)
{
if (forcedTypes == null || forcedTypes.Count() == 0)
throw new ArgumentException("Cannot configure a forced BSON class map serialization provider which contains no types to be forced as BSON class maps", "forcedTypes");
if (!forcedTypes.All(type => type.IsClass || type.IsInterface))
throw new ArgumentException("Forced types must be classes or interfaces");
_forcedTypes = new HashSet<Type>(forcedTypes);
}
/// <summary>
/// Gets a set of types to be forced as BSON class maps during their serialization.
/// </summary>
public HashSet<Type> ForcedTypes { get { return _forcedTypes; } }
/// <inheritdoc/>
public override IBsonSerializer GetSerializer(Type type, IBsonSerializerRegistry serializerRegistry)
{
// Forcing can happen either if type to be serialized is within forced type set, or if one of forced types
// is implemented or inherited by the given type.
if (ForcedTypes.Contains(type) || ForcedTypes.Any(forcedType => forcedType.IsAssignableFrom(type)))
{
BsonClassMapSerializationProvider bsonClassMapProvider = new BsonClassMapSerializationProvider();
return bsonClassMapProvider.GetSerializer(type);
}
return null;
}
}
}