Browse files

CSHARP-584: rewrote convention system to be more flexible and more pr…

…edictable.
  • Loading branch information...
1 parent 715f1fd commit 93b2f6e853732d56bf80ad952def72b09f29130e @craiggwilson craiggwilson committed Dec 24, 2012
Showing with 5,147 additions and 642 deletions.
  1. +2 −2 .gitignore
  2. +61 −0 MongoDB.Bson/Exceptions/DuplicateBsonMemberMapAttributeException.cs
  3. +48 −13 MongoDB.Bson/MongoDB.Bson.csproj
  4. +4 −2 MongoDB.Bson/Serialization/Attributes/BsonDefaultValueAttribute.cs
  5. +3 −1 MongoDB.Bson/Serialization/Attributes/BsonDiscriminatorAttribute.cs
  6. +3 −1 MongoDB.Bson/Serialization/Attributes/BsonElementAttribute.cs
  7. +4 −1 MongoDB.Bson/Serialization/Attributes/BsonExtraElementsAttribute.cs
  8. +5 −3 MongoDB.Bson/Serialization/Attributes/BsonIdAttribute.cs
  9. +3 −1 MongoDB.Bson/Serialization/Attributes/BsonIgnoreExtraElementsAttribute.cs
  10. +3 −1 MongoDB.Bson/Serialization/Attributes/BsonIgnoreIfDefaultAttribute.cs
  11. +3 −1 MongoDB.Bson/Serialization/Attributes/BsonIgnoreIfNullAttribute.cs
  12. +3 −1 MongoDB.Bson/Serialization/Attributes/BsonKnownTypesAttribute.cs
  13. +52 −0 MongoDB.Bson/Serialization/Attributes/BsonMemberMapAttributeUsageAttribute.cs
  14. +3 −1 MongoDB.Bson/Serialization/Attributes/BsonRequiredAttribute.cs
  15. +3 −1 MongoDB.Bson/Serialization/Attributes/BsonSerializationOptionsAttribute.cs
  16. +3 −1 MongoDB.Bson/Serialization/Attributes/BsonSerializerAttribute.cs
  17. +34 −0 MongoDB.Bson/Serialization/Attributes/IBsonClassMapAttribute.cs
  18. +4 −3 MongoDB.Bson/Serialization/Attributes/IBsonClassMapModifier.cs
  19. +34 −0 MongoDB.Bson/Serialization/Attributes/IBsonMemberMapAttribute.cs
  20. +4 −3 MongoDB.Bson/Serialization/Attributes/IBsonMemberMapModifier.cs
  21. +70 −189 MongoDB.Bson/Serialization/BsonClassMap.cs
  22. +27 −61 MongoDB.Bson/Serialization/BsonMemberMap.cs
  23. +189 −0 MongoDB.Bson/Serialization/Conventions/AttributeConventionPack.cs
  24. +72 −0 MongoDB.Bson/Serialization/Conventions/CamelCaseElementNameConvention.cs
  25. +75 −0 MongoDB.Bson/Serialization/Conventions/ConventionBase.cs
  26. +221 −0 MongoDB.Bson/Serialization/Conventions/ConventionPack.cs
  27. +159 −0 MongoDB.Bson/Serialization/Conventions/ConventionRegistry.cs
  28. +72 −0 MongoDB.Bson/Serialization/Conventions/ConventionRunner.cs
  29. +70 −0 MongoDB.Bson/Serialization/Conventions/DefaultConventionPack.cs
  30. +57 −0 MongoDB.Bson/Serialization/Conventions/DelegateClassMapConvention.cs
  31. +57 −0 MongoDB.Bson/Serialization/Conventions/DelegateMemberMapConvention.cs
  32. +57 −0 MongoDB.Bson/Serialization/Conventions/DelegatePostProcessingConvention.cs
  33. +0 −67 MongoDB.Bson/Serialization/Conventions/ExtraElementsMemberConventions.cs
  34. +73 −0 MongoDB.Bson/Serialization/Conventions/HierarchicalDiscriminatorConvention.cs
  35. +34 −0 MongoDB.Bson/Serialization/Conventions/IClassMapConvention.cs
  36. +33 −0 MongoDB.Bson/Serialization/Conventions/IConvention.cs
  37. +33 −0 MongoDB.Bson/Serialization/Conventions/IConventionPack.cs
  38. +53 −0 MongoDB.Bson/Serialization/Conventions/IDiscriminatorConvention.cs
  39. +34 −0 MongoDB.Bson/Serialization/Conventions/IMemberMapConvention.cs
  40. +34 −0 MongoDB.Bson/Serialization/Conventions/IPostProcessingConvention.cs
  41. +0 −74 MongoDB.Bson/Serialization/Conventions/IdMemberConventions.cs
  42. +50 −0 MongoDB.Bson/Serialization/Conventions/IgnoreExtraElementsConvention.cs
  43. +50 −0 MongoDB.Bson/Serialization/Conventions/IgnoreIfDefaultConvention.cs
  44. +50 −0 MongoDB.Bson/Serialization/Conventions/IgnoreIfNullConvention.cs
  45. +63 −0 MongoDB.Bson/Serialization/Conventions/LookupIdGeneratorConvention.cs
  46. +58 −0 MongoDB.Bson/Serialization/Conventions/MemberDefaultValueConvention.cs
  47. +13 −31 ...B.Bson/Serialization/Conventions/{ElementNameConventions.cs → MemberNameElementNameConvention.cs}
  48. +58 −0 MongoDB.Bson/Serialization/Conventions/MemberSerializationOptionsConvention.cs
  49. +149 −0 MongoDB.Bson/Serialization/Conventions/NamedExtraElementsMemberConvention.cs
  50. +138 −0 MongoDB.Bson/Serialization/Conventions/NamedIdMemberConvention.cs
  51. +298 −4 MongoDB.Bson/Serialization/Conventions/{ → Obsolete}/ConventionProfile.cs
  52. +3 −1 MongoDB.Bson/Serialization/Conventions/{ → Obsolete}/DefaultValueConventions.cs
  53. +37 −0 MongoDB.Bson/Serialization/Conventions/Obsolete/ElementNameConventions.cs
  54. +37 −0 MongoDB.Bson/Serialization/Conventions/Obsolete/ExtraElementsMemberConventions.cs
  55. +2 −17 MongoDB.Bson/Serialization/Conventions/{ → Obsolete}/IdGeneratorConventions.cs
  56. +37 −0 MongoDB.Bson/Serialization/Conventions/Obsolete/IdMemberConventions.cs
  57. +4 −1 MongoDB.Bson/Serialization/Conventions/{ → Obsolete}/IgnoreExtraElementsConventions.cs
  58. +5 −2 MongoDB.Bson/Serialization/Conventions/{ → Obsolete}/IgnoreIfDefaultConventions.cs
  59. +4 −1 MongoDB.Bson/Serialization/Conventions/{ → Obsolete}/IgnoreIfNullConventions.cs
  60. +3 −1 MongoDB.Bson/Serialization/Conventions/{ → Obsolete}/MemberFinderConventions.cs
  61. +5 −2 MongoDB.Bson/Serialization/Conventions/{ → Obsolete}/SerializationOptionsConventions.cs
  62. +4 −4 MongoDB.Bson/Serialization/Conventions/{ → Obsolete}/SerializeDefaultValueConventions.cs
  63. +133 −0 MongoDB.Bson/Serialization/Conventions/ReadWriteMemberFinderConvention.cs
  64. +38 −0 MongoDB.Bson/Serialization/Conventions/ResetClassMapConvention.cs
  65. +39 −0 MongoDB.Bson/Serialization/Conventions/ResetMemberMapsConvention.cs
  66. +55 −0 MongoDB.Bson/Serialization/Conventions/ScalarDiscriminatorConvention.cs
  67. +1 −104 ...Bson/Serialization/Conventions/{DiscriminatorConventions.cs → StandardDiscriminatorConvention.cs}
  68. +51 −0 MongoDB.Bson/Serialization/Conventions/StringObjectIdIdGeneratorConvention.cs
  69. +13 −15 MongoDB.BsonUnitTests/Jira/CSharp310Tests.cs
  70. +18 −1 MongoDB.BsonUnitTests/MongoDB.BsonUnitTests.csproj
  71. +16 −19 MongoDB.BsonUnitTests/Serialization/BsonClassMapAutoMappingTests.cs
  72. +74 −6 MongoDB.BsonUnitTests/Serialization/BsonClassMapTests.cs
  73. +37 −0 MongoDB.BsonUnitTests/Serialization/BsonMemberMapTests.cs
  74. +94 −0 MongoDB.BsonUnitTests/Serialization/Conventions/AttributeConventionPackTests.cs
  75. +60 −0 MongoDB.BsonUnitTests/Serialization/Conventions/CamelCaseElementNameConventionsTests.cs
  76. +156 −0 MongoDB.BsonUnitTests/Serialization/Conventions/ConventionPackTests.cs
  77. +202 −0 MongoDB.BsonUnitTests/Serialization/Conventions/ConventionRunnerTests.cs
  78. +50 −0 MongoDB.BsonUnitTests/Serialization/Conventions/DelegateClassMapConventionTests.cs
  79. +51 −0 MongoDB.BsonUnitTests/Serialization/Conventions/DelegateMemberMapConventionTests.cs
  80. +50 −0 MongoDB.BsonUnitTests/Serialization/Conventions/DelegatePostProcessingConventionTests.cs
  81. +4 −0 MongoDB.BsonUnitTests/Serialization/Conventions/ElementNameConventionsTests.cs
  82. +2 −0 MongoDB.BsonUnitTests/Serialization/Conventions/ExtraElementsConventionsTests.cs
  83. +2 −0 MongoDB.BsonUnitTests/Serialization/Conventions/IdGeneratorConventionsTests.cs
  84. +2 −0 MongoDB.BsonUnitTests/Serialization/Conventions/IdMemberConventionsTests.cs
  85. +49 −0 MongoDB.BsonUnitTests/Serialization/Conventions/IgnoreExtraElementsConventionsTests.cs
  86. +50 −0 MongoDB.BsonUnitTests/Serialization/Conventions/IgnoreIfDefaultConventionsTests.cs
  87. +50 −0 MongoDB.BsonUnitTests/Serialization/Conventions/IgnoreIfNullConventionsTests.cs
  88. +85 −0 MongoDB.BsonUnitTests/Serialization/Conventions/MemberDefaultValueConventionTests.cs
  89. +60 −0 MongoDB.BsonUnitTests/Serialization/Conventions/MemberNameElementNameConventionsTests.cs
  90. +117 −0 MongoDB.BsonUnitTests/Serialization/Conventions/NamedExtraElementsConventionsTests.cs
  91. +102 −0 MongoDB.BsonUnitTests/Serialization/Conventions/NamedIdConventionsTests.cs
  92. +2 −1 MongoDB.BsonUnitTests/Serialization/Conventions/PropertyFinderConventionsTests.cs
  93. +73 −0 MongoDB.BsonUnitTests/Serialization/Conventions/ReadWriteMemberFinderConventionsTests.cs
  94. +93 −0 MongoDB.BsonUnitTests/Serialization/Conventions/StringObjectIdGeneratorConventionsTests.cs
  95. +544 −0 MongoDB.BsonUnitTests/Serialization/LegacyBsonClassMapTests.cs
  96. +7 −5 MongoDB.DriverUnitTests/Jira/CSharp77Tests.cs
View
4 .gitignore
@@ -28,7 +28,7 @@ Help
*.swp
*~
-#Nupkg artifacts
+# Nupkg artifacts
*.nupkg
# NCrunch artifacts
@@ -39,4 +39,4 @@ Help
*.vb.orig
# Other
-artifacts
+artifacts
View
61 MongoDB.Bson/Exceptions/DuplicateBsonMemberMapAttributeException.cs
@@ -0,0 +1,61 @@
+/* Copyright 2010-2012 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
+{
+ /// <summary>
+ /// Indicates that an attribute restricted to one member has been applied to multiple members.
+ /// </summary>
+ [Serializable]
+ public class DuplicateBsonMemberMapAttributeException : BsonException
+ {
+ // constructors
+ /// <summary>
+ /// Initializes a new instance of the <see cref="DuplicateBsonMemberMapAttributeException" /> class.
+ /// </summary>
+ /// <param name="message">The message.</param>
+ public DuplicateBsonMemberMapAttributeException(string message)
+ : base(message)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="DuplicateBsonMemberMapAttributeException" /> class.
+ /// </summary>
+ /// <param name="message">The message.</param>
+ /// <param name="inner">The inner.</param>
+ public DuplicateBsonMemberMapAttributeException(string message, Exception inner)
+ : base(message, inner)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="DuplicateBsonMemberMapAttributeException" /> class.
+ /// </summary>
+ /// <param name="info">The info.</param>
+ /// <param name="context">The context.</param>
+ protected DuplicateBsonMemberMapAttributeException(
+ System.Runtime.Serialization.SerializationInfo info,
+ System.Runtime.Serialization.StreamingContext context)
+ : base(info, context)
+ {
+ }
+ }
+}
View
61 MongoDB.Bson/MongoDB.Bson.csproj
@@ -83,6 +83,7 @@
<Link>Properties\GlobalAssemblyInfo.cs</Link>
</Compile>
<Compile Include="BsonExtensionMethods.cs" />
+ <Compile Include="Exceptions\DuplicateBsonMemberMapAttributeException.cs" />
<Compile Include="IO\BsonDocumentReaderSettings.cs" />
<Compile Include="IO\BsonDocumentWriterSettings.cs" />
<Compile Include="IO\BsonReaderSettings.cs" />
@@ -97,12 +98,58 @@
<Compile Include="Serialization\Attributes\BsonDictionaryOptionsAttribute.cs" />
<Compile Include="Serialization\Attributes\BsonExtraElementsAttribute.cs" />
<Compile Include="Serialization\Attributes\BsonIgnoreIfDefaultAttribute.cs" />
+ <Compile Include="Serialization\Attributes\BsonMemberMapAttributeUsageAttribute.cs" />
<Compile Include="Serialization\Attributes\BsonRepresentationAttribute.cs" />
<Compile Include="Serialization\Attributes\BsonSerializationOptionsAttribute.cs" />
<Compile Include="Serialization\Attributes\BsonSerializerAttribute.cs" />
<Compile Include="Serialization\Attributes\BsonTimeSpanOptionsAttribute.cs" />
+ <Compile Include="Serialization\Attributes\IBsonMemberMapAttribute.cs" />
+ <Compile Include="Serialization\Attributes\IBsonClassMapAttribute.cs" />
<Compile Include="Serialization\BsonClassMapSerializationProvider.cs" />
<Compile Include="Serialization\BsonDocumentBackedClass.cs" />
+ <Compile Include="Serialization\Conventions\AttributeConventionPack.cs" />
+ <Compile Include="Serialization\Conventions\CamelCaseElementNameConvention.cs" />
+ <Compile Include="Serialization\Conventions\ConventionBase.cs" />
+ <Compile Include="Serialization\Conventions\ConventionPack.cs" />
+ <Compile Include="Serialization\Conventions\ConventionRegistry.cs" />
+ <Compile Include="Serialization\Conventions\ConventionRunner.cs" />
+ <Compile Include="Serialization\Conventions\DefaultConventionPack.cs" />
+ <Compile Include="Serialization\Conventions\DelegateClassMapConvention.cs" />
+ <Compile Include="Serialization\Conventions\DelegateMemberMapConvention.cs" />
+ <Compile Include="Serialization\Conventions\DelegatePostProcessingConvention.cs" />
+ <Compile Include="Serialization\Conventions\HierarchicalDiscriminatorConvention.cs" />
+ <Compile Include="Serialization\Conventions\IClassMapConvention.cs" />
+ <Compile Include="Serialization\Conventions\IConvention.cs" />
+ <Compile Include="Serialization\Conventions\IConventionPack.cs" />
+ <Compile Include="Serialization\Conventions\IgnoreExtraElementsConvention.cs" />
+ <Compile Include="Serialization\Conventions\IgnoreIfDefaultConvention.cs" />
+ <Compile Include="Serialization\Conventions\IgnoreIfNullConvention.cs" />
+ <Compile Include="Serialization\Conventions\IMemberMapConvention.cs" />
+ <Compile Include="Serialization\Conventions\IPostProcessingConvention.cs" />
+ <Compile Include="Serialization\Conventions\LookupIdGeneratorConvention.cs" />
+ <Compile Include="Serialization\Conventions\MemberDefaultValueConvention.cs" />
+ <Compile Include="Serialization\Conventions\MemberNameElementNameConvention.cs" />
+ <Compile Include="Serialization\Conventions\MemberSerializationOptionsConvention.cs" />
+ <Compile Include="Serialization\Conventions\NamedExtraElementsMemberConvention.cs" />
+ <Compile Include="Serialization\Conventions\NamedIdMemberConvention.cs" />
+ <Compile Include="Serialization\Conventions\Obsolete\ConventionProfile.cs" />
+ <Compile Include="Serialization\Conventions\Obsolete\DefaultValueConventions.cs" />
+ <Compile Include="Serialization\Conventions\Obsolete\ElementNameConventions.cs" />
+ <Compile Include="Serialization\Conventions\Obsolete\ExtraElementsMemberConventions.cs" />
+ <Compile Include="Serialization\Conventions\Obsolete\IdGeneratorConventions.cs" />
+ <Compile Include="Serialization\Conventions\Obsolete\IdMemberConventions.cs" />
+ <Compile Include="Serialization\Conventions\Obsolete\IgnoreExtraElementsConventions.cs" />
+ <Compile Include="Serialization\Conventions\Obsolete\IgnoreIfDefaultConventions.cs" />
+ <Compile Include="Serialization\Conventions\Obsolete\IgnoreIfNullConventions.cs" />
+ <Compile Include="Serialization\Conventions\Obsolete\MemberFinderConventions.cs" />
+ <Compile Include="Serialization\Conventions\Obsolete\SerializationOptionsConventions.cs" />
+ <Compile Include="Serialization\Conventions\Obsolete\SerializeDefaultValueConventions.cs" />
+ <Compile Include="Serialization\Conventions\ReadWriteMemberFinderConvention.cs" />
+ <Compile Include="Serialization\Conventions\ResetClassMapConvention.cs" />
+ <Compile Include="Serialization\Conventions\ResetMemberMapsConvention.cs" />
+ <Compile Include="Serialization\Conventions\ScalarDiscriminatorConvention.cs" />
+ <Compile Include="Serialization\Conventions\StandardDiscriminatorConvention.cs" />
+ <Compile Include="Serialization\Conventions\StringObjectIdIdGeneratorConvention.cs" />
<Compile Include="Serialization\IdGenerators\BsonBinaryDataGuidGenerator.cs" />
<Compile Include="Serialization\IdGenerators\BsonObjectIdGenerator.cs" />
<Compile Include="Serialization\IdGenerators\CombGuidGenerator.cs" />
@@ -119,9 +166,6 @@
<Compile Include="Serialization\Serializers\BsonBooleanSerializer.cs" />
<Compile Include="Serialization\Serializers\BsonDateTimeSerializer.cs" />
<Compile Include="Serialization\Serializers\BsonDocumentBackedClassSerializer.cs" />
- <Compile Include="Serialization\Conventions\ExtraElementsMemberConventions.cs" />
- <Compile Include="Serialization\Conventions\IgnoreIfDefaultConventions.cs" />
- <Compile Include="Serialization\Conventions\SerializationOptionsConventions.cs" />
<Compile Include="Serialization\Attributes\IBsonClassMapModifier.cs" />
<Compile Include="Serialization\IBsonArraySerializer.cs" />
<Compile Include="Serialization\Attributes\IBsonMemberMapModifier.cs" />
@@ -150,16 +194,7 @@
<Compile Include="IO\JsonToken.cs" />
<Compile Include="ObjectModel\BsonUndefined.cs" />
<Compile Include="Serialization\IBsonSerializationOptions.cs" />
- <Compile Include="Serialization\Conventions\ConventionProfile.cs" />
- <Compile Include="Serialization\Conventions\IdGeneratorConventions.cs" />
- <Compile Include="Serialization\Conventions\DefaultValueConventions.cs" />
- <Compile Include="Serialization\Conventions\DiscriminatorConventions.cs" />
- <Compile Include="Serialization\Conventions\MemberFinderConventions.cs" />
- <Compile Include="Serialization\Conventions\SerializeDefaultValueConventions.cs" />
- <Compile Include="Serialization\Conventions\IgnoreIfNullConventions.cs" />
- <Compile Include="Serialization\Conventions\ElementNameConventions.cs" />
- <Compile Include="Serialization\Conventions\IdMemberConventions.cs" />
- <Compile Include="Serialization\Conventions\IgnoreExtraElementsConventions.cs" />
+ <Compile Include="Serialization\Conventions\IDiscriminatorConvention.cs" />
<Compile Include="Serialization\Options\TimeSpanSerializationOptions.cs" />
<Compile Include="Serialization\Options\TimeSpanUnits.cs" />
<Compile Include="Serialization\BsonSerializationInfo.cs" />
View
6 MongoDB.Bson/Serialization/Attributes/BsonDefaultValueAttribute.cs
@@ -24,7 +24,9 @@ namespace MongoDB.Bson.Serialization.Attributes
/// Specifies the default value for a field or property.
/// </summary>
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
- public class BsonDefaultValueAttribute : Attribute, IBsonMemberMapModifier
+#pragma warning disable 618 // obsoleted by IBsonMemberMapModifier
+ public class BsonDefaultValueAttribute : Attribute, IBsonMemberMapAttribute, IBsonMemberMapModifier
+#pragma warning restore 618
{
// private fields
private object _defaultValue;
@@ -53,7 +55,7 @@ public object DefaultValue
/// <summary>
/// Gets or sets whether to serialize the default value.
/// </summary>
- [Obsolete("SerializeDefaultValue is obsolete and will be removed in a future version of the C# driver. Please use BsonIgnoreIfDefaultAttribute instead.")]
+ [Obsolete("Use BsonIgnoreIfDefaultAttribute instead.")]
public bool SerializeDefaultValue
{
get { return _serializeDefaultValue; }
View
4 MongoDB.Bson/Serialization/Attributes/BsonDiscriminatorAttribute.cs
@@ -24,7 +24,9 @@ namespace MongoDB.Bson.Serialization.Attributes
/// Specifies the discriminator and related options for a class.
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct)]
- public class BsonDiscriminatorAttribute : Attribute, IBsonClassMapModifier
+#pragma warning disable 618 // obsoleted by IBsonClassMapModifier
+ public class BsonDiscriminatorAttribute : Attribute, IBsonClassMapAttribute, IBsonClassMapModifier
+#pragma warning restore 618
{
// private fields
private string _discriminator;
View
4 MongoDB.Bson/Serialization/Attributes/BsonElementAttribute.cs
@@ -24,7 +24,9 @@ namespace MongoDB.Bson.Serialization.Attributes
/// Specifies the element name and related options for a field or property.
/// </summary>
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
- public class BsonElementAttribute : Attribute, IBsonMemberMapModifier
+#pragma warning disable 618 // obsoleted by IBsonMemberMapModifier
+ public class BsonElementAttribute : Attribute, IBsonMemberMapAttribute, IBsonMemberMapModifier
+#pragma warning restore 618
{
// private fields
private string _elementName;
View
5 MongoDB.Bson/Serialization/Attributes/BsonExtraElementsAttribute.cs
@@ -24,7 +24,10 @@ namespace MongoDB.Bson.Serialization.Attributes
/// Indicates that this property or field will be used to hold any extra elements found during deserialization.
/// </summary>
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
- public class BsonExtraElementsAttribute : Attribute, IBsonMemberMapModifier
+ [BsonMemberMapAttributeUsage(AllowMultipleMembers = false)]
+#pragma warning disable 618 // obsoleted by IBsonMemberMapModifier
+ public class BsonExtraElementsAttribute : Attribute, IBsonMemberMapAttribute, IBsonMemberMapModifier
+#pragma warning restore 618
{
// public methods
/// <summary>
View
8 MongoDB.Bson/Serialization/Attributes/BsonIdAttribute.cs
@@ -24,7 +24,10 @@ namespace MongoDB.Bson.Serialization.Attributes
/// Specifies that this is the Id field or property.
/// </summary>
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
- public class BsonIdAttribute : Attribute, IBsonMemberMapModifier
+ [BsonMemberMapAttributeUsage(AllowMultipleMembers = false)]
+#pragma warning disable 618 // obsoleted by IBsonMemberMapModifier
+ public class BsonIdAttribute : Attribute, IBsonMemberMapAttribute, IBsonMemberMapModifier
+#pragma warning restore 618
{
// private fields
private Type _idGenerator;
@@ -64,7 +67,6 @@ public int Order
/// <param name="memberMap">The member map.</param>
public void Apply(BsonMemberMap memberMap)
{
- memberMap.SetElementName("_id");
memberMap.SetOrder(_order);
if (_idGenerator != null)
{
@@ -74,4 +76,4 @@ public void Apply(BsonMemberMap memberMap)
memberMap.ClassMap.SetIdMember(memberMap);
}
}
-}
+}
View
4 MongoDB.Bson/Serialization/Attributes/BsonIgnoreExtraElementsAttribute.cs
@@ -24,7 +24,9 @@ namespace MongoDB.Bson.Serialization.Attributes
/// Specifies whether extra elements should be ignored when this class is deserialized.
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct)]
- public class BsonIgnoreExtraElementsAttribute : Attribute, IBsonClassMapModifier
+#pragma warning disable 618 // obsoleted by IBsonClassMapModifier
+ public class BsonIgnoreExtraElementsAttribute : Attribute, IBsonClassMapAttribute, IBsonClassMapModifier
+#pragma warning restore 618
{
// private fields
private bool _ignoreExtraElements;
View
4 MongoDB.Bson/Serialization/Attributes/BsonIgnoreIfDefaultAttribute.cs
@@ -24,7 +24,9 @@ namespace MongoDB.Bson.Serialization.Attributes
/// Indicates whether a field or property equal to the default value should be ignored when serializing this class.
/// </summary>
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
- public class BsonIgnoreIfDefaultAttribute : Attribute, IBsonMemberMapModifier
+#pragma warning disable 618 // obsoleted by IBsonMemberMapModifier
+ public class BsonIgnoreIfDefaultAttribute : Attribute, IBsonMemberMapAttribute, IBsonMemberMapModifier
+#pragma warning restore 618
{
// private fields
private bool _value;
View
4 MongoDB.Bson/Serialization/Attributes/BsonIgnoreIfNullAttribute.cs
@@ -24,7 +24,9 @@ namespace MongoDB.Bson.Serialization.Attributes
/// Indicates whether a field or property equal to null should be ignored when serializing this class.
/// </summary>
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
- public class BsonIgnoreIfNullAttribute : Attribute, IBsonMemberMapModifier
+#pragma warning disable 618 // obsoleted by IBsonMemberMapModifier
+ public class BsonIgnoreIfNullAttribute : Attribute, IBsonMemberMapAttribute, IBsonMemberMapModifier
+#pragma warning restore 618
{
// private fields
private bool _value;
View
4 MongoDB.Bson/Serialization/Attributes/BsonKnownTypesAttribute.cs
@@ -24,7 +24,9 @@ namespace MongoDB.Bson.Serialization.Attributes
/// Specifies the known types for this class (the derived classes).
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = true)]
- public class BsonKnownTypesAttribute : Attribute, IBsonClassMapModifier
+#pragma warning disable 618 // obsoleted by IBsonMemberMapModifier
+ public class BsonKnownTypesAttribute : Attribute, IBsonClassMapAttribute, IBsonClassMapModifier
+#pragma warning restore 618
{
// private fields
private Type[] _knownTypes;
View
52 MongoDB.Bson/Serialization/Attributes/BsonMemberMapAttributeUsageAttribute.cs
@@ -0,0 +1,52 @@
+/* Copyright 2010-2012 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
+{
+ /// <summary>
+ /// Indicates the usage restrictions for the attribute.
+ /// </summary>
+ [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
+ public class BsonMemberMapAttributeUsageAttribute : Attribute
+ {
+ // private fields
+ private bool _allowMultipleMembers;
+
+ // constructors
+ /// <summary>
+ /// Initializes a new instance of the <see cref="BsonMemberMapAttributeUsageAttribute" /> class.
+ /// </summary>
+ public BsonMemberMapAttributeUsageAttribute()
+ {
+ _allowMultipleMembers = true;
+ }
+
+ // public properties
+ /// <summary>
+ /// Gets or sets a value indicating whether the attribute this attribute applies to is allowed to be applied
+ /// to more than one member.
+ /// </summary>
+ public bool AllowMultipleMembers
+ {
+ get { return _allowMultipleMembers; }
+ set { _allowMultipleMembers = value; }
+ }
+ }
+}
View
4 MongoDB.Bson/Serialization/Attributes/BsonRequiredAttribute.cs
@@ -24,7 +24,9 @@ namespace MongoDB.Bson.Serialization.Attributes
/// Indicates that a field or property is required.
/// </summary>
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
- public class BsonRequiredAttribute : Attribute, IBsonMemberMapModifier
+#pragma warning disable 618 // obsoleted by IBsonMemberMapModifier
+ public class BsonRequiredAttribute : Attribute, IBsonMemberMapAttribute, IBsonMemberMapModifier
+#pragma warning restore 618
{
// public methods
/// <summary>
View
4 MongoDB.Bson/Serialization/Attributes/BsonSerializationOptionsAttribute.cs
@@ -26,7 +26,9 @@ namespace MongoDB.Bson.Serialization.Attributes
/// <summary>
/// Abstract base class for serialization options attributes.
/// </summary>
- public abstract class BsonSerializationOptionsAttribute : Attribute, IBsonMemberMapModifier
+#pragma warning disable 618 // obsoleted by IBsonMemberMapModifier
+ public abstract class BsonSerializationOptionsAttribute : Attribute, IBsonMemberMapAttribute, IBsonMemberMapModifier
+#pragma warning disable 618
{
// constructors
/// <summary>
View
4 MongoDB.Bson/Serialization/Attributes/BsonSerializerAttribute.cs
@@ -24,7 +24,9 @@ namespace MongoDB.Bson.Serialization.Attributes
/// Specifies the type of the serializer to use for a class.
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Property | AttributeTargets.Field)]
- public class BsonSerializerAttribute : Attribute, IBsonMemberMapModifier
+#pragma warning disable 618 // obsoleted by IBsonMemberMapModifier
+ public class BsonSerializerAttribute : Attribute, IBsonMemberMapAttribute, IBsonMemberMapModifier
+#pragma warning restore 618
{
// private fields
private Type _serializerType;
View
34 MongoDB.Bson/Serialization/Attributes/IBsonClassMapAttribute.cs
@@ -0,0 +1,34 @@
+/* Copyright 2010-2012 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
+{
+ /// <summary>
+ /// Represents an attribute used to modify a class map.
+ /// </summary>
+ public interface IBsonClassMapAttribute
+ {
+ /// <summary>
+ /// Applies the attribute to the class map.
+ /// </summary>
+ /// <param name="classMap">The class map.</param>
+ void Apply(BsonClassMap classMap);
+ }
+}
View
7 MongoDB.Bson/Serialization/Attributes/IBsonClassMapModifier.cs
@@ -21,14 +21,15 @@
namespace MongoDB.Bson.Serialization
{
/// <summary>
- /// Modifies a class map.
+ /// Represents an attribute used to modify a class map.
/// </summary>
+ [Obsolete("Use IBsonClassMapAttribute instead.")]
public interface IBsonClassMapModifier
{
/// <summary>
- /// Applies a modification to the class map.
+ /// Applies the attribute to the class map.
/// </summary>
/// <param name="classMap">The class map.</param>
void Apply(BsonClassMap classMap);
}
-}
+}
View
34 MongoDB.Bson/Serialization/Attributes/IBsonMemberMapAttribute.cs
@@ -0,0 +1,34 @@
+/* Copyright 2010-2012 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
+{
+ /// <summary>
+ /// Represents an attribute used to modify a member map.
+ /// </summary>
+ public interface IBsonMemberMapAttribute
+ {
+ /// <summary>
+ /// Applies the attribute to the member map.
+ /// </summary>
+ /// <param name="memberMap">The member map.</param>
+ void Apply(BsonMemberMap memberMap);
+ }
+}
View
7 MongoDB.Bson/Serialization/Attributes/IBsonMemberMapModifier.cs
@@ -21,14 +21,15 @@
namespace MongoDB.Bson.Serialization
{
/// <summary>
- /// Modifies a member map.
+ /// Represents an attribute used to modify a member map.
/// </summary>
+ [Obsolete("Use IBsonMemberMapAttribute instead.")]
public interface IBsonMemberMapModifier
{
/// <summary>
- /// Applies a modification to the member map.
+ /// Applies the attribute to the member map.
/// </summary>
/// <param name="memberMap">The member map.</param>
void Apply(BsonMemberMap memberMap);
}
-}
+}
View
259 MongoDB.Bson/Serialization/BsonClassMap.cs
@@ -26,9 +26,7 @@
using System.Text.RegularExpressions;
using MongoDB.Bson.IO;
-using MongoDB.Bson.Serialization.Attributes;
using MongoDB.Bson.Serialization.Conventions;
-using MongoDB.Bson.Serialization.Options;
namespace MongoDB.Bson.Serialization
{
@@ -38,19 +36,18 @@ namespace MongoDB.Bson.Serialization
public abstract class BsonClassMap
{
// private static fields
- private static List<FilteredConventionProfile> __profiles = new List<FilteredConventionProfile>();
- private static ConventionProfile __defaultProfile = ConventionProfile.GetDefault();
- private static Dictionary<Type, BsonClassMap> __classMaps = new Dictionary<Type, BsonClassMap>();
+ private readonly static Dictionary<Type, BsonClassMap> __classMaps = new Dictionary<Type, BsonClassMap>();
+ private readonly static Queue<Type> __knownTypesQueue = new Queue<Type>();
+
private static int __freezeNestingLevel = 0;
- private static Queue<Type> __knownTypesQueue = new Queue<Type>();
// private fields
private bool _frozen; // once a class map has been frozen no further changes are allowed
private BsonClassMap _baseClassMap; // null for class object and interfaces
private Type _classType;
private volatile IDiscriminatorConvention _cachedDiscriminatorConvention;
private Func<object> _creator;
- private ConventionProfile _conventions;
+ private IConventionPack _conventionPack;
private string _discriminator;
private bool _discriminatorIsRequired;
private bool _hasRootClass;
@@ -61,8 +58,8 @@ public abstract class BsonClassMap
private readonly ReadOnlyCollection<BsonMemberMap> _allMemberMapsReadonly;
private readonly List<BsonMemberMap> _declaredMemberMaps; // only the members declared in this class
private readonly BsonTrie<int> _elementTrie;
- private bool _ignoreExtraElements = true;
- private bool _ignoreExtraElementsIsInherited = false;
+ private bool _ignoreExtraElements;
+ private bool _ignoreExtraElementsIsInherited;
private BsonMemberMap _extraElementsMemberMap;
private int _extraElementsMemberIndex = -1;
private List<Type> _knownTypes = new List<Type>();
@@ -75,13 +72,14 @@ public abstract class BsonClassMap
protected BsonClassMap(Type classType)
{
_classType = classType;
- _conventions = LookupConventions(classType);
- _discriminator = classType.Name;
+ _conventionPack = ConventionRegistry.Lookup(classType);
_isAnonymous = IsAnonymousType(classType);
_allMemberMaps = new List<BsonMemberMap>();
- _declaredMemberMaps = new List<BsonMemberMap>();
_allMemberMapsReadonly = _allMemberMaps.AsReadOnly();
+ _declaredMemberMaps = new List<BsonMemberMap>();
_elementTrie = new BsonTrie<int>();
+
+ Reset();
}
// public properties
@@ -110,11 +108,29 @@ public Type ClassType
}
/// <summary>
+ /// Gets the conventions used for auto mapping.
+ /// </summary>
+ public IConventionPack ConventionPack
+ {
+ get { return _conventionPack; }
+ }
+
+ /// <summary>
/// Gets the conventions used with this class.
/// </summary>
+ [Obsolete("Use ConventionPack instead.")]
public ConventionProfile Conventions
{
- get { return _conventions; }
+ get
+ {
+ var profile = _conventionPack as ConventionProfile;
+ if (profile != null)
+ {
+ return profile;
+ }
+
+ throw new NotSupportedException("This class map was setup using an IConventionPack, part of the new conventions api. Use the ConventionPack property for access to the conventions.");
+ }
}
/// <summary>
@@ -213,15 +229,6 @@ public IEnumerable<Type> KnownTypes
get { return _knownTypes; }
}
- /// <summary>
- /// Gets the member maps.
- /// </summary>
- [Obsolete("Use AllMemberMaps or DeclaredMemberMaps instead.")]
- public IEnumerable<BsonMemberMap> MemberMaps
- {
- get { return _allMemberMaps; }
- }
-
// internal properties
/// <summary>
/// Gets the element name to member index trie.
@@ -351,22 +358,18 @@ public static BsonClassMap LookupClassMap(Type classType)
/// </summary>
/// <param name="type">The type.</param>
/// <returns>The conventions profile for that type.</returns>
+ [Obsolete("Use ConventionRegistry.Lookup instead.")]
public static ConventionProfile LookupConventions(Type type)
{
- if (type == null)
+ var pack = ConventionRegistry.Lookup(type);
+ var profile = pack as ConventionProfile;
+ if (profile != null)
{
- throw new ArgumentNullException("type");
+ return profile;
}
- for (int i = 0; i < __profiles.Count; i++)
- {
- if (__profiles[i].Filter(type))
- {
- return __profiles[i].Profile;
- }
- }
-
- return __defaultProfile;
+ var message = string.Format("Type {0} was setup using an IConventionPack, part of the new conventions api. Use the ConventionPack property for access to the conventions.", type);
+ throw new NotSupportedException(message);
}
/// <summary>
@@ -421,25 +424,10 @@ public static void RegisterClassMap(BsonClassMap classMap)
/// </summary>
/// <param name="conventions">The conventions profile.</param>
/// <param name="filter">The filter function that determines which types this profile applies to.</param>
+ [Obsolete("Use ConventionRegistry.Register instead.")]
public static void RegisterConventions(ConventionProfile conventions, Func<Type, bool> filter)
{
- if (conventions == null)
- {
- throw new ArgumentNullException("conventions");
- }
- if (filter == null)
- {
- throw new ArgumentNullException("filter");
- }
-
- conventions.Merge(__defaultProfile); // make sure all conventions exists
- var filtered = new FilteredConventionProfile
- {
- Filter = filter,
- Profile = conventions
- };
- // add new conventions to the front of the list
- __profiles.Insert(0, filtered);
+ ConventionRegistry.Register("conventions", conventions, filter);
}
// public methods
@@ -512,20 +500,11 @@ public BsonClassMap Freeze()
{
_idMemberMap = _baseClassMap.IdMemberMap;
}
-
- // if our base class did not have an idMemberMap maybe we have one?
- if (_idMemberMap == null)
- {
- var memberName = _conventions.IdMemberConvention.FindIdMember(_classType);
- if (memberName != null)
- {
- var memberMap = GetMemberMap(memberName);
- if (memberMap != null)
- {
- SetIdMember(memberMap);
- }
- }
- }
+ }
+ else
+ {
+ // conventions could have set this to an improper value
+ _idMemberMap.SetElementName("_id");
}
if (_extraElementsMemberMap == null)
@@ -535,20 +514,6 @@ public BsonClassMap Freeze()
{
_extraElementsMemberMap = _baseClassMap.ExtraElementsMemberMap;
}
-
- // if our base class did not have an extraElementsMemberMap maybe we have one?
- if (_extraElementsMemberMap == null)
- {
- var memberName = _conventions.ExtraElementsMemberConvention.FindExtraElementsMember(_classType);
- if (memberName != null)
- {
- var memberMap = GetMemberMap(memberName);
- if (memberMap != null)
- {
- SetExtraElementsMember(memberMap);
- }
- }
- }
}
_extraElementsMemberIndex = -1;
@@ -836,6 +801,25 @@ public BsonMemberMap MapProperty(string propertyName)
}
/// <summary>
+ /// Resets the class map back to its initial state.
+ /// </summary>
+ public void Reset()
+ {
+ if (_frozen) { ThrowFrozenException(); }
+
+ _creator = null;
+ _declaredMemberMaps.Clear();
+ _discriminator = _classType.Name;
+ _discriminatorIsRequired = false;
+ _extraElementsMemberMap = null;
+ _idMemberMap = null;
+ _ignoreExtraElements = true; // TODO: should this really be false?
+ _ignoreExtraElementsIsInherited = false;
+ _isRootClass = false;
+ _knownTypes.Clear();
+ }
+
+ /// <summary>
/// Sets the creator for the object.
/// </summary>
/// <param name="creator">The creator.</param>
@@ -884,11 +868,6 @@ public void SetExtraElementsMember(BsonMemberMap memberMap)
EnsureMemberMapIsForThisClass(memberMap);
if (_frozen) { ThrowFrozenException(); }
- if (_extraElementsMemberMap != null)
- {
- var message = string.Format("Class {0} already has an extra elements member.", _classType.FullName);
- throw new InvalidOperationException(message);
- }
if (memberMap.MemberType != typeof(BsonDocument) && !typeof(IDictionary<string, object>).IsAssignableFrom(memberMap.MemberType))
{
var message = string.Format("Type of ExtraElements member must be BsonDocument or implement IDictionary<string, object>.");
@@ -927,13 +906,7 @@ public void SetIdMember(BsonMemberMap memberMap)
EnsureMemberMapIsForThisClass(memberMap);
if (_frozen) { ThrowFrozenException(); }
- if (_idMemberMap != null)
- {
- var message = string.Format("Class {0} already has an Id.", _classType.FullName);
- throw new InvalidOperationException(message);
- }
- memberMap.SetElementName("_id");
_idMemberMap = memberMap;
}
@@ -1058,24 +1031,22 @@ internal IDiscriminatorConvention GetDiscriminatorConvention()
// private methods
private void AutoMapClass()
{
- _ignoreExtraElements = _conventions.IgnoreExtraElementsConvention.IgnoreExtraElements(_classType);
+ new ConventionRunner(_conventionPack).Apply(this);
- foreach (IBsonClassMapModifier attribute in _classType.GetCustomAttributes(typeof(IBsonClassMapModifier), false))
+ OrderMembers();
+ foreach (var memberMap in _declaredMemberMaps)
{
- attribute.Apply(this);
+ TryFindShouldSerializeMethod(memberMap);
}
-
- AutoMapMembers();
}
- private void AutoMapMembers()
+ private void OrderMembers()
{
// only auto map properties declared in this class (and not in base classes)
var hasOrderedElements = false;
var hasUnorderedElements = false;
- foreach (var memberInfo in FindMembers())
+ foreach (var memberMap in _declaredMemberMaps)
{
- var memberMap = AutoMapMember(memberInfo);
if (memberMap.Order != int.MaxValue)
{
hasOrderedElements |= true;
@@ -1103,50 +1074,14 @@ private void AutoMapMembers()
}
}
- private BsonMemberMap AutoMapMember(MemberInfo memberInfo)
+ private void TryFindShouldSerializeMethod(BsonMemberMap memberMap)
{
- var memberMap = MapMember(memberInfo);
-
- memberMap.SetElementName(_conventions.ElementNameConvention.GetElementName(memberInfo));
- bool ignoreIfDefault;
-#pragma warning disable 618 // SerializeDefaultValueConvention is obsolete
- if (_conventions.SerializeDefaultValueConvention != null)
- {
- ignoreIfDefault = !_conventions.SerializeDefaultValueConvention.SerializeDefaultValue(memberInfo);
- }
-#pragma warning restore 618
- else
- {
- ignoreIfDefault = _conventions.IgnoreIfDefaultConvention.IgnoreIfDefault(memberInfo);
- }
- memberMap.SetIgnoreIfDefault(ignoreIfDefault);
- memberMap.SetIgnoreIfNull(_conventions.IgnoreIfNullConvention.IgnoreIfNull(memberInfo));
-
- var defaultValue = _conventions.DefaultValueConvention.GetDefaultValue(memberInfo);
- if (defaultValue != null)
- {
- memberMap.SetDefaultValue(defaultValue);
- }
-
// see if the class has a method called ShouldSerializeXyz where Xyz is the name of this member
- var shouldSerializeMethod = GetShouldSerializeMethod(memberInfo);
+ var shouldSerializeMethod = GetShouldSerializeMethod(memberMap.MemberInfo);
if (shouldSerializeMethod != null)
{
memberMap.SetShouldSerializeMethod(shouldSerializeMethod);
}
-
- var serializationOptions = _conventions.SerializationOptionsConvention.GetSerializationOptions(memberInfo);
- if (serializationOptions != null)
- {
- memberMap.SetSerializationOptions(serializationOptions);
- }
-
- foreach (IBsonMemberMapModifier attribute in memberInfo.GetCustomAttributes(typeof(IBsonMemberMapModifier), false))
- {
- attribute.Apply(memberMap);
- }
-
- return memberMap;
}
private void EnsureMemberInfoIsForThisClass(MemberInfo memberInfo)
@@ -1173,53 +1108,6 @@ private void EnsureMemberMapIsForThisClass(BsonMemberMap memberMap)
}
}
- private IEnumerable<MemberInfo> FindMembers()
- {
- // use a List instead of a HashSet to preserver order
- var memberInfos = new List<MemberInfo>(_conventions.MemberFinderConvention.FindMembers(_classType));
-
- // let other fields opt-in if they have a BsonElement attribute
- foreach (var fieldInfo in _classType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly))
- {
- var elementAttribute = (BsonElementAttribute)fieldInfo.GetCustomAttributes(typeof(BsonElementAttribute), false).FirstOrDefault();
- if (elementAttribute == null)
- {
- continue;
- }
-
- if (!memberInfos.Contains(fieldInfo))
- {
- memberInfos.Add(fieldInfo);
- }
- }
-
- // let other properties opt-in if they have a BsonElement attribute
- foreach (var propertyInfo in _classType.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly))
- {
- var elementAttribute = (BsonElementAttribute)propertyInfo.GetCustomAttributes(typeof(BsonElementAttribute), false).FirstOrDefault();
- if (elementAttribute == null)
- {
- continue;
- }
-
- if (!memberInfos.Contains(propertyInfo))
- {
- memberInfos.Add(propertyInfo);
- }
- }
-
- foreach (var memberInfo in memberInfos)
- {
- var ignoreAttribute = (BsonIgnoreAttribute)memberInfo.GetCustomAttributes(typeof(BsonIgnoreAttribute), false).FirstOrDefault();
- if (ignoreAttribute != null)
- {
- continue; // ignore this property
- }
-
- yield return memberInfo;
- }
- }
-
private Func<object> GetCreator()
{
if (_creator == null)
@@ -1283,13 +1171,6 @@ private void ThrowNotFrozenException()
var message = string.Format("Class map for {0} has been not been frozen yet.", _classType.FullName);
throw new InvalidOperationException(message);
}
-
- // private class
- private class FilteredConventionProfile
- {
- public Func<Type, bool> Filter;
- public ConventionProfile Profile;
- }
}
/// <summary>
View
88 MongoDB.Bson/Serialization/BsonMemberMap.cs
@@ -24,7 +24,6 @@
using MongoDB.Bson.IO;
using MongoDB.Bson.Serialization;
using MongoDB.Bson.Serialization.Conventions;
-using MongoDB.Bson.Serialization.IdGenerators;
using MongoDB.Bson.Serialization.Options;
namespace MongoDB.Bson.Serialization
@@ -37,7 +36,7 @@ public class BsonMemberMap
// private fields
private BsonClassMap _classMap;
private string _elementName;
- private int _order = int.MaxValue;
+ private int _order;
private MemberInfo _memberInfo;
private Type _memberType;
private bool _memberTypeIsBsonValue;
@@ -67,8 +66,8 @@ public BsonMemberMap(BsonClassMap classMap, MemberInfo memberInfo)
_memberInfo = memberInfo;
_memberType = BsonClassMap.GetMemberInfoType(memberInfo);
_memberTypeIsBsonValue = typeof(BsonValue).IsAssignableFrom(_memberType);
- _defaultValue = GetDefaultValue(_memberType);
- _defaultValueSpecified = false;
+
+ Reset();
}
// public properties
@@ -109,14 +108,7 @@ public bool MemberTypeIsBsonValue
/// </summary>
public string ElementName
{
- get
- {
- if (_elementName == null)
- {
- _elementName = _classMap.Conventions.ElementNameConvention.GetElementName(_memberInfo);
- }
- return _elementName;
- }
+ get { return _elementName; }
}
/// <summary>
@@ -185,24 +177,7 @@ public IBsonSerializationOptions SerializationOptions
/// </summary>
public IIdGenerator IdGenerator
{
- get
- {
- if (_idGenerator == null)
- {
- // special case IdGenerator for strings represented externally as ObjectId
- var memberInfoType = BsonClassMap.GetMemberInfoType(_memberInfo);
- var representationOptions = _serializationOptions as RepresentationSerializationOptions;
- if (memberInfoType == typeof(string) && representationOptions != null && representationOptions.Representation == BsonType.ObjectId)
- {
- _idGenerator = StringObjectIdGenerator.Instance;
- }
- else
- {
- _idGenerator = _classMap.Conventions.IdGeneratorConvention.GetIdGenerator(_memberInfo);
- }
- }
- return _idGenerator;
- }
+ get { return _idGenerator; }
}
/// <summary>
@@ -214,15 +189,6 @@ public bool IsRequired
}
/// <summary>
- /// Gets whether the default value should be serialized.
- /// </summary>
- [Obsolete("SerializeDefaultValue is obsolete and will be removed in a future version of the C# Driver. Please use IgnoreIfDefault instead.")]
- public bool SerializeDefaultValue
- {
- get { return !_ignoreIfDefault; }
- }
-
- /// <summary>
/// Gets the method that will be called to determine whether the member should be serialized.
/// </summary>
public Func<object, bool> ShouldSerializeMethod
@@ -329,28 +295,35 @@ public IBsonSerializer GetSerializer(Type actualType)
}
/// <summary>
- /// Sets the default value.
+ /// Resets the member map back to its initial state.
/// </summary>
- /// <param name="defaultValue">The default value.</param>
/// <returns>The member map.</returns>
- public BsonMemberMap SetDefaultValue(object defaultValue)
+ public BsonMemberMap Reset()
{
- _defaultValue = defaultValue;
- _defaultValueSpecified = true;
+ _defaultValue = GetDefaultValue(_memberType);
+ _defaultValueSpecified = false;
+ _elementName = _memberInfo.Name;
+ _idGenerator = null;
+ _ignoreIfDefault = false;
+ _ignoreIfNull = false;
+ _isRequired = false;
+ _order = int.MaxValue;
+ _serializationOptions = null;
+ _serializer = null;
+ _shouldSerializeMethod = null;
+
return this;
}
/// <summary>
/// Sets the default value.
/// </summary>
/// <param name="defaultValue">The default value.</param>
- /// <param name="serializeDefaultValue">Whether the default value shoudl be serialized.</param>
/// <returns>The member map.</returns>
- [Obsolete("This overload of SetDefaultValue is obsolete and will be removed in a future version of the C# driver. Please use SetDefaultValue(defaultValue) and SetIgnoreIfDefault instead.")]
- public BsonMemberMap SetDefaultValue(object defaultValue, bool serializeDefaultValue)
+ public BsonMemberMap SetDefaultValue(object defaultValue)
{
- SetDefaultValue(defaultValue);
- SetIgnoreIfDefault(!serializeDefaultValue);
+ _defaultValue = defaultValue;
+ _defaultValueSpecified = true;
return this;
}
@@ -361,6 +334,11 @@ public BsonMemberMap SetDefaultValue(object defaultValue, bool serializeDefaultV
/// <returns>The member map.</returns>
public BsonMemberMap SetElementName(string elementName)
{
+ if (elementName == null)
+ {
+ throw new ArgumentNullException("elementName");
+ }
+
_elementName = elementName;
return this;
}
@@ -462,18 +440,6 @@ public BsonMemberMap SetSerializer(IBsonSerializer serializer)
}
/// <summary>
- /// Sets whether the default value should be serialized.
- /// </summary>
- /// <param name="serializeDefaultValue">Whether the default value should be serialized.</param>
- /// <returns>The member map.</returns>
- [Obsolete("SetSerializeDefaultValue is obsolete and will be removed in a future version of the C# driver. Please use SetIgnoreIfDefault instead.")]
- public BsonMemberMap SetSerializeDefaultValue(bool serializeDefaultValue)
- {
- _ignoreIfDefault = !serializeDefaultValue;
- return this;
- }
-
- /// <summary>
/// Sets the method that will be called to determine whether the member should be serialized.
/// </summary>
/// <param name="shouldSerializeMethod">The method.</param>
View
189 MongoDB.Bson/Serialization/Conventions/AttributeConventionPack.cs
@@ -0,0 +1,189 @@
+/* Copyright 2010-2012 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 MongoDB.Bson.Serialization.Attributes;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+
+namespace MongoDB.Bson.Serialization.Conventions
+{
+ /// <summary>
+ /// Convention pack for applying attributes.
+ /// </summary>
+ public class AttributeConventionPack : IConventionPack
+ {
+ // private static fields
+ private static readonly AttributeConventionPack __attributeConventionPack = new AttributeConventionPack();
+
+ // private fields
+ private readonly AttributeConvention _attributeConvention;
+
+ // constructors
+ /// <summary>
+ /// Initializes a new instance of the <see cref="AttributeConventionPack" /> class.
+ /// </summary>
+ private AttributeConventionPack()
+ {
+ _attributeConvention = new AttributeConvention();
+ }
+
+ // public static properties
+ /// <summary>
+ /// Gets the instance.
+ /// </summary>
+ public static IConventionPack Instance
+ {
+ get { return __attributeConventionPack; }
+ }
+
+ // public properties
+ /// <summary>
+ /// Gets the conventions.
+ /// </summary>
+ public IEnumerable<IConvention> Conventions
+ {
+ get { yield return _attributeConvention; }
+ }
+
+ // nested classes
+ private class AttributeConvention : ConventionBase, IClassMapConvention, IMemberMapConvention
+ {
+ // public methods
+ public void Apply(BsonClassMap classMap)
+ {
+ foreach (IBsonClassMapAttribute attribute in classMap.ClassType.GetCustomAttributes(typeof(IBsonClassMapAttribute), false))
+ {
+ attribute.Apply(classMap);
+ }
+#pragma warning disable 618 // obsoleted by IBsonClassMapModifier
+ foreach (IBsonClassMapModifier attribute in classMap.ClassType.GetCustomAttributes(typeof(IBsonClassMapModifier), false))
+ {
+ // only apply this if it wasn't already applied
+ if (!(attribute is IBsonClassMapAttribute))
+ {
+ attribute.Apply(classMap);
+ }
+ }
+#pragma warning restore 618
+
+ OptInMembersWithBsonMemberMapModifierAttribute(classMap);
+ IgnoreMembersWithBsonIgnoreAttribute(classMap);
+ ThrowForDuplicateMemberMapAttributes(classMap);
+ }
+
+ public void Apply(BsonMemberMap memberMap)
+ {
+ foreach (IBsonMemberMapAttribute attribute in memberMap.MemberInfo.GetCustomAttributes(typeof(IBsonMemberMapAttribute), false))
+ {
+ attribute.Apply(memberMap);
+ }
+#pragma warning disable 618 // obsoleted by IBsonMemberMapModifier
+ foreach (IBsonMemberMapModifier attribute in memberMap.MemberInfo.GetCustomAttributes(typeof(IBsonMemberMapModifier), false))
+ {
+ // only apply this if it wasn't already applied
+ if (!(attribute is IBsonMemberMapAttribute))
+ {
+ attribute.Apply(memberMap);
+ }
+ }
+#pragma warning restore 618
+ }
+
+ // private methods
+ private bool AllowsDuplicate(Type type)
+ {
+ var usageAttribute = type.GetCustomAttributes(typeof(BsonMemberMapAttributeUsageAttribute), true)
+ .OfType<BsonMemberMapAttributeUsageAttribute>()
+ .SingleOrDefault();
+
+ return usageAttribute == null || usageAttribute.AllowMultipleMembers;
+ }
+
+ private void OptInMembersWithBsonMemberMapModifierAttribute(BsonClassMap classMap)
+ {
+ // let other fields opt-in if they have any IBsonMemberMapAttribute attributes
+ foreach (var fieldInfo in classMap.ClassType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly))
+ {
+#pragma warning disable 618 // obsoleted by IBsonMemberMapModifier
+ var hasAttribute = fieldInfo.GetCustomAttributes(typeof(IBsonMemberMapAttribute), false).Any()
+ || fieldInfo.GetCustomAttributes(typeof(IBsonMemberMapModifier), false).Any();
+#pragma warning restore 618
+
+ if (hasAttribute)
+ {
+ classMap.MapMember(fieldInfo);
+ }
+ }
+
+ // let other properties opt-in if they have any IBsonMemberMapAttribute attributes
+ foreach (var propertyInfo in classMap.ClassType.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly))
+ {
+#pragma warning disable 618 // obsoleted by IBsonMemberMapModifier
+ var hasAttribute = propertyInfo.GetCustomAttributes(typeof(IBsonMemberMapAttribute), false).Any()
+ || propertyInfo.GetCustomAttributes(typeof(IBsonMemberMapModifier), false).Any();
+#pragma warning restore 618
+ if (hasAttribute)
+ {
+ classMap.MapMember(propertyInfo);
+ }
+ }
+ }
+
+ private void IgnoreMembersWithBsonIgnoreAttribute(BsonClassMap classMap)
+ {
+ foreach (var memberMap in classMap.DeclaredMemberMaps.ToList())
+ {
+ var ignoreAttribute = (BsonIgnoreAttribute)memberMap.MemberInfo.GetCustomAttributes(typeof(BsonIgnoreAttribute), false).FirstOrDefault();
+ if (ignoreAttribute != null)
+ {
+ classMap.UnmapMember(memberMap.MemberInfo);
+ }
+ }
+ }
+
+ private void ThrowForDuplicateMemberMapAttributes(BsonClassMap classMap)
+ {
+ var nonDuplicatesAlreadySeen = new List<Type>();
+ foreach (var memberMap in classMap.DeclaredMemberMaps)
+ {
+ var attributes = (IBsonMemberMapAttribute[])memberMap.MemberInfo.GetCustomAttributes(typeof(IBsonMemberMapAttribute), false);
+#pragma warning disable 618 // obsoleted by IBsonMemberMapModifier
+ var legacyAttributes = (IBsonMemberMapModifier[])memberMap.MemberInfo.GetCustomAttributes(typeof(IBsonMemberMapModifier), false);
+ // combine them only if the modifier isn't already in the attributes list...
+ var attributeTypes = attributes
+ .Select(x => x.GetType())
+ .Union(legacyAttributes.Where(x => !(x is IBsonMemberMapAttribute)).Select(x => x.GetType()));
+#pragma warning restore 618
+ foreach (var attributeType in attributeTypes)
+ {
+ if (nonDuplicatesAlreadySeen.Contains(attributeType))
+ {
+ var message = string.Format("Attributes of type {0} can only be applied to a single member.", attributeType);
+ throw new DuplicateBsonMemberMapAttributeException(message);
+ }
+
+ if (!AllowsDuplicate(attributeType))
+ {
+ nonDuplicatesAlreadySeen.Add(attributeType);
+ }
+ }
+ }
+ }
+ }
+ }
+}
View
72 MongoDB.Bson/Serialization/Conventions/CamelCaseElementNameConvention.cs
@@ -0,0 +1,72 @@
+/* Copyright 2010-2012 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.Reflection;
+using System.Text;
+
+namespace MongoDB.Bson.Serialization.Conventions
+{
+ /// <summary>
+ /// A convention that sets the element name the same as the member name with the first character lower cased.
+ /// </summary>
+#pragma warning disable 618 // about obsolete IElementNameConvention
+ public class CamelCaseElementNameConvention : ConventionBase, IMemberMapConvention, IElementNameConvention
+#pragma warning restore 618
+ {
+ // public methods
+ /// <summary>
+ /// Applies a modification to the member map.
+ /// </summary>
+ /// <param name="memberMap">The member map.</param>
+ public void Apply(BsonMemberMap memberMap)
+ {
+ string name = memberMap.MemberName;
+ name = GetElementName(name);
+ memberMap.SetElementName(name);
+ }
+
+ /// <summary>
+ /// Gets the element name for a member.
+ /// </summary>
+ /// <param name="member">The member.</param>
+ /// <returns>The element name.</returns>
+ [Obsolete("Use Apply instead.")]
+ public string GetElementName(MemberInfo member)
+ {
+ string name = member.Name;
+ return GetElementName(name);
+ }
+
+ // private methods
+ private string GetElementName(string memberName)
+ {
+ if (memberName.Length == 0)
+ {
+ return "";
+ }
+ else if(memberName.Length == 1)
+ {
+ return Char.ToLowerInvariant(memberName[0]).ToString();
+ }
+ else
+ {
+ return Char.ToLowerInvariant(memberName[0]) + memberName.Substring(1);
+ }
+ }
+ }
+}
View
75 MongoDB.Bson/Serialization/Conventions/ConventionBase.cs
@@ -0,0 +1,75 @@
+/* Copyright 2010-2012 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.Conventions
+{
+ /// <summary>
+ /// Base class for a convention.
+ /// </summary>
+ public abstract class ConventionBase : IConvention
+ {
+ // private fields
+ private readonly string _name;
+
+ // constructors
+ /// <summary>
+ /// Initializes a new instance of the ConventionBase class.
+ /// </summary>
+ protected ConventionBase()
+ {
+ _name = GetName(this.GetType());
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the ConventionBase class.
+ /// </summary>
+ /// <param name="name">The name of the convention.</param>
+ protected ConventionBase(string name)
+ {
+ if (name == null)
+ {
+ throw new ArgumentNullException("name");
+ }
+
+ _name = name;
+ }
+
+ // public properties
+ /// <summary>
+ /// Gets the name of the convention.
+ /// </summary>
+ public string Name
+ {
+ get { return _name; }
+ }
+
+ // private static methods
+ private static string GetName(Type type)
+ {
+ var name = type.Name;
+ if (name.EndsWith("Convention"))
+ {
+ return name.Substring(0, name.Length - 10);
+ }
+
+ return name;
+ }
+ }
+}
View
221 MongoDB.Bson/Serialization/Conventions/ConventionPack.cs
@@ -0,0 +1,221 @@
+/* Copyright 2010-2012 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;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace MongoDB.Bson.Serialization.Conventions
+{
+ /// <summary>
+ /// A mutable pack of conventions.
+ /// </summary>
+ public class ConventionPack : IConventionPack, IEnumerable<IConvention>
+ {
+ // private fields
+ private readonly List<IConvention> _conventions;
+
+ // constructors
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ConventionPack" /> class.
+ /// </summary>
+ public ConventionPack()
+ {
+ _conventions = new List<IConvention>();
+ }
+
+ // public properties
+ /// <summary>
+ /// Gets the conventions.
+ /// </summary>
+ public IEnumerable<IConvention> Conventions
+ {
+ get { return _conventions; }
+ }
+
+ // public methods
+ /// <summary>
+ /// Adds the specified convention.
+ /// </summary>
+ /// <param name="convention">The convention.</param>
+ /// <exception cref="System.ArgumentNullException"></exception>
+ public void Add(IConvention convention)
+ {
+ if (convention == null)
+ {
+ throw new ArgumentNullException("convention");
+ }
+
+ _conventions.Add(convention);
+ }
+
+ /// <summary>
+ /// Adds a class map convention created using the specified action upon a class map.
+ /// </summary>
+ /// <param name="name">The name of the convention.</param>
+ /// <param name="action">The action the convention should take upon the class map.</param>
+ public void AddClassMapConvention(string name, Action<BsonClassMap> action)
+ {
+ if (name == null)
+ {
+ throw new ArgumentNullException("name");
+ }
+
+ Add(new DelegateClassMapConvention(name, action));
+ }
+
+ /// <summary>
+ /// Adds a member map convention created using the specified action upon a member map.
+ /// </summary>
+ /// <param name="name">The name of the convention.</param>
+ /// <param name="action">The action the convention should take upon the member map.</param>
+ public void AddMemberMapConvention(string name, Action<BsonMemberMap> action)
+ {
+ if (name == null)
+ {
+ throw new ArgumentNullException("name");
+ }
+
+ Add(new DelegateMemberMapConvention(name, action));
+ }
+
+ /// <summary>
+ /// Adds a post processing convention created using the specified action upon a class map.
+ /// </summary>
+ /// <param name="name">The name of the convention.</param>
+ /// <param name="action">The action the convention should take upon the class map.</param>
+ public void AddPostProcessingConvention(string name, Action<BsonClassMap> action)
+ {
+ if (name == null)
+ {
+ throw new ArgumentNullException("name");
+ }
+
+ Add(new DelegatePostProcessingConvention(name, action));
+ }
+
+ /// <summary>
+ /// Adds a range of conventions.
+ /// </summary>
+ /// <param name="conventions">The conventions.</param>
+ /// <exception cref="System.ArgumentNullException"></exception>
+ public void AddRange(IEnumerable<IConvention> conventions)
+ {
+ if (conventions == null)
+ {
+ throw new ArgumentNullException("conventions");
+ }
+
+ _conventions.AddRange(conventions);
+ }
+
+ /// <summary>
+ /// Appends the conventions in another pack to the end of this pack.
+ /// </summary>
+ /// <param name="other">The other pack.</param>
+ public void Append(IConventionPack other)
+ {
+ if (other == null)
+ {
+ throw new ArgumentNullException("other");
+ }
+
+ AddRange(other.Conventions);
+ }
+
+ /// <summary>
+ /// Gets an enumerator for the conventions.
+ /// </summary>
+ /// <returns>An enumerator.</returns>
+ public IEnumerator<IConvention> GetEnumerator()
+ {
+ return _conventions.GetEnumerator();
+ }
+
+ /// <summary>
+ /// Inserts the convention after another convention specified by the name.
+ /// </summary>
+ /// <param name="name">The name.</param>
+ /// <param name="convention">The convention.</param>
+ public void InsertAfter(string name, IConvention convention)
+ {
+ if (name == null)
+ {
+ throw new ArgumentNullException("name");
+ }
+ if (convention == null)
+ {
+ throw new ArgumentNullException("convention");
+ }
+
+ var index = _conventions.FindIndex(x => x.Name == name);
+ if (index == -1)
+ {
+ var message = string.Format("Unable to find a convention by the name of '{0}'.", name);
+ throw new ArgumentOutOfRangeException("name", message);
+ }
+
+ _conventions.Insert(index + 1, convention);
+ }
+
+ /// <summary>
+ /// Inserts the convention before another convention specified by the name.
+ /// </summary>
+ /// <param name="name">The name.</param>
+ /// <param name="convention">The convention.</param>
+ public void InsertBefore(string name, IConvention convention)
+ {
+ if (name == null)
+ {
+ throw new ArgumentNullException("name");
+ }
+ if (convention == null)
+ {
+ throw new ArgumentNullException("convention");
+ }
+
+ var index = _conventions.FindIndex(x => x.Name == name);
+ if (index == -1)
+ {
+ var message = string.Format("Unable to find a convention by the name of '{0}'.", name);
+ throw new ArgumentOutOfRangeException("name", message);
+ }
+
+ _conventions.Insert(index, convention);
+ }
+
+ /// <summary>
+ /// Removes the named convention.
+ /// </summary>
+ /// <param name="name">The name of the convention.</param>
+ public void Remove(string name)
+ {
+ if (name == null)
+ {
+ throw new ArgumentNullException("name");
+ }
+
+ _conventions.RemoveAll(x => x.Name == name);
+ }
+
+ // explicit interface implementations
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return _conventions.GetEnumerator();
+ }
+ }
+}
View
159 MongoDB.Bson/Serialization/Conventions/ConventionRegistry.cs
@@ -0,0 +1,159 @@
+/* Copyright 2010-2012 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.Conventions
+{
+ /// <summary>
+ /// Represents a registry of conventions.
+ /// </summary>
+ public static class ConventionRegistry
+ {
+ // private static fields
+ private readonly static List<ConventionPackContainer> __conventionPacks = new List<ConventionPackContainer>();
+ private readonly static object __lock = new object();
+
+ // static constructors
+ static ConventionRegistry()
+ {
+ Register("__defaults__", DefaultConventionPack.Instance, t => true);
+ Register("__attributes__", AttributeConventionPack.Instance, t => true);
+ }
+
+ // public static methods
+ /// <summary>
+ /// Looks up the effective set of conventions that apply to a type.
+ /// </summary>
+ /// <param name="type">The type.</param>
+ /// <returns>The conventions for that type.</returns>
+ public static IConventionPack Lookup(Type type)
+ {
+ if (type == null)
+ {
+ throw new ArgumentNullException("type");
+ }
+
+ lock (__lock)
+ {
+ var pack = new ConventionPack();
+
+ // append any attribute packs (usually just one) at the end so attributes are processed last
+ var attributePacks = new List<IConventionPack>();
+#pragma warning disable 618 //obsoleted by ConventionProfile
+ ConventionProfile conventionProfile = null;
+#pragma warning restore 618
+ foreach (var container in __conventionPacks)
+ {
+ if (container.Filter(type))
+ {
+#pragma warning disable 618 //obsoleted by ConventionProfile
+ if (container.Pack is ConventionProfile)
+ {
+ conventionProfile = container.Pack as ConventionProfile;
+ }
+#pragma warning restore 618
+
+ if (container.Name == "__attributes__")
+ {
+ attributePacks.Add(container.Pack);
+ }
+ else
+ {
+ pack.Append(container.Pack);
+ }
+ }
+ }
+ if (conventionProfile != null)
+ {
+ // already includes the default attribute convention pack
+ return conventionProfile;
+ }
+
+ foreach (var attributePack in attributePacks)
+ {
+ pack.Append(attributePack);
+ }
+
+ return pack;
+ }
+ }
+
+ /// <summary>
+ /// Registers the conventions.
+ /// </summary>
+ /// <param name="name">The name.</param>
+ /// <param name="conventions">The conventions.</param>
+ /// <param name="filter">The filter.</param>
+ public static void Register(string name, IConventionPack conventions, Func<Type, bool> filter)
+ {
+ if (name == null)
+ {
+ throw new ArgumentNullException("name");
+ }
+ if (conventions == null)
+ {
+ throw new ArgumentNullException("conventions");
+ }
+ if (filter == null)
+ {
+ throw new ArgumentNullException("filter");
+ }
+
+ lock (__lock)
+ {
+ var container = new ConventionPackContainer
+ {
+ Filter = filter,
+ Name = name,
+ Pack = conventions
+ };
+
+ __conventionPacks.Add(container);
+ }
+ }
+
+ /// <summary>
+ /// Removes the conventions specified by the given name.
+ /// </summary>
+ /// <param name="name">The name.</param>
+ /// <remarks>Removing a convention allows the removal of the special __defaults__ conventions
+ /// and the __attributes__ conventions for those who want to completely customize the
+ /// experience.</remarks>
+ public static void Remove(string name)
+ {
+ if (name == null)
+ {
+ throw new ArgumentNullException("name");
+ }
+
+ lock (__lock)
+ {
+ __conventionPacks.RemoveAll(x => x.Name == name);
+ }
+ }
+
+ // private class
+ private class ConventionPackContainer
+ {
+ public Func<Type, bool> Filter;
+ public string Name;
+ public IConventionPack Pack;
+ }
+ }
+}
View
72 MongoDB.Bson/Serialization/Conventions/ConventionRunner.cs
@@ -0,0 +1,72 @@
+/* Copyright 2010-2012 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.Conventions
+{
+ /// <summary>
+ /// Runs the conventions against a BsonClassMap and its BsonMemberMaps.
+ /// </summary>
+ public class ConventionRunner
+ {
+ // private fields
+ private readonly IEnumerable<IConvention> _conventions;
+
+ // constructors
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ConventionRunner" /> class.
+ /// </summary>
+ /// <param name="conventions">The conventions.</param>
+ public ConventionRunner(IConventionPack conventions)
+ {
+ if (conventions == null)
+ {
+ throw new ArgumentNullException("conventions");
+ }
+
+ _conventions = conventions.Conventions.ToList();
+ }
+
+ // public methods
+ /// <summary>
+ /// Applies a modification to the class map.
+ /// </summary>
+ /// <param name="classMap">The class map.</param>
+ public void Apply(BsonClassMap classMap)
+ {
+ foreach (var convention in _conventions.OfType<IClassMapConvention>())
+ {
+ convention.Apply(classMap);
+ }
+
+ foreach (var convention in _conventions.OfType<IMemberMapConvention>())
+ {
+ foreach (var memberMap in classMap.DeclaredMemberMaps)
+ {
+ convention.Apply(memberMap);
+ }
+ }
+
+ foreach (var convention in _conventions.OfType<IPostProcessingConvention>())
+ {
+ convention.PostProcess(classMap);
+ }
+ }
+ }
+}
View
70 MongoDB.Bson/Serialization/Conventions/DefaultConventionPack.cs
@@ -0,0 +1,70 @@
+/* Copyright 2010-2012 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.Reflection;
+using System.Text;
+
+namespace MongoDB.Bson.Serialization.Conventions
+{
+ /// <summary>
+ /// Convention pack of defaults.
+ /// </summary>
+ public class DefaultConventionPack : IConventionPack
+ {
+ // private static fields
+ private static readonly IConventionPack __defaultConventionPack = new DefaultConventionPack();
+
+ // private fields
+ private readonly IEnumerable<IConvention> _conventions;
+
+ // constructors
+ /// <summary>
+ /// Initializes a new instance of the <see cref="DefaultConventionPack" /> class.
+ /// </summary>
+ private DefaultConventionPack()
+ {
+ _conventions = new List<IConvention>
+ {
+ new ReadWriteMemberFinderConvention(),
+ new NamedIdMemberConvention(new [] { "Id", "id", "_id" }),
+ new NamedExtraElementsMemberConvention(new [] { "ExtraElements" }),
+ new IgnoreExtraElementsConvention(false),
+ new StringObjectIdIdGeneratorConvention(), // should be before LookupIdGeneratorConvention
+ new LookupIdGeneratorConvention()
+ };
+ }
+
+ // public static properties
+ /// <summary>
+ /// Gets the instance.
+ /// </summary>
+ public static IConventionPack Instance
+ {
+ get { return __defaultConventionPack; }
+ }
+
+ // public properties
+ /// <summary>
+ /// Gets the conventions.
+ /// </summary>
+ public IEnumerable<IConvention> Conventions
+ {
+ get { return _conventions; }
+ }
+ }