BsonSerializerAttribute.cs 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. /* Copyright 2010-present MongoDB Inc.
  2. *
  3. * Licensed under the Apache License, Version 2.0 (the "License");
  4. * you may not use this file except in compliance with the License.
  5. * You may obtain a copy of the License at
  6. *
  7. * http://www.apache.org/licenses/LICENSE-2.0
  8. *
  9. * Unless required by applicable law or agreed to in writing, software
  10. * distributed under the License is distributed on an "AS IS" BASIS,
  11. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. * See the License for the specific language governing permissions and
  13. * limitations under the License.
  14. */
  15. using System;
  16. using System.Reflection;
  17. namespace MongoDB.Bson.Serialization.Attributes
  18. {
  19. /// <summary>
  20. /// Specifies the type of the serializer to use for a class.
  21. /// </summary>
  22. [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface | AttributeTargets.Property | AttributeTargets.Field)]
  23. public class BsonSerializerAttribute : Attribute, IBsonMemberMapAttribute
  24. {
  25. // private fields
  26. private Type _serializerType;
  27. // constructors
  28. /// <summary>
  29. /// Initializes a new instance of the BsonSerializerAttribute class.
  30. /// </summary>
  31. public BsonSerializerAttribute()
  32. {
  33. }
  34. /// <summary>
  35. /// Initializes a new instance of the BsonSerializerAttribute class.
  36. /// </summary>
  37. /// <param name="serializerType">The type of the serializer to use for a class.</param>
  38. public BsonSerializerAttribute(Type serializerType)
  39. {
  40. _serializerType = serializerType;
  41. }
  42. // public properties
  43. /// <summary>
  44. /// Gets or sets the type of the serializer to use for a class.
  45. /// </summary>
  46. public Type SerializerType
  47. {
  48. get { return _serializerType; }
  49. set { _serializerType = value; }
  50. }
  51. // public methods
  52. /// <summary>
  53. /// Applies a modification to the member map.
  54. /// </summary>
  55. /// <param name="memberMap">The member map.</param>
  56. public void Apply(BsonMemberMap memberMap)
  57. {
  58. var serializer = CreateSerializer(memberMap.MemberType);
  59. memberMap.SetSerializer(serializer);
  60. }
  61. /// <summary>
  62. /// Creates a serializer for a type based on the serializer type specified by the attribute.
  63. /// </summary>
  64. /// <param name="type">The type that a serializer should be created for.</param>
  65. /// <returns>A serializer for the type.</returns>
  66. internal IBsonSerializer CreateSerializer(Type type)
  67. {
  68. var typeInfo = type.GetTypeInfo();
  69. if (typeInfo.ContainsGenericParameters)
  70. {
  71. var message = "Cannot create a serializer because the type to serialize is an open generic type.";
  72. throw new InvalidOperationException(message);
  73. }
  74. var serializerTypeInfo = _serializerType.GetTypeInfo();
  75. if (serializerTypeInfo.ContainsGenericParameters && !typeInfo.IsGenericType)
  76. {
  77. var message = "Cannot create a serializer because the serializer type is an open generic type and the type to serialize is not generic.";
  78. throw new InvalidOperationException(message);
  79. }
  80. if (serializerTypeInfo.ContainsGenericParameters)
  81. {
  82. var genericArguments = typeInfo.GetGenericArguments();
  83. var closedSerializerType = _serializerType.MakeGenericType(genericArguments);
  84. return (IBsonSerializer)Activator.CreateInstance(closedSerializerType);
  85. }
  86. else
  87. {
  88. return (IBsonSerializer)Activator.CreateInstance(_serializerType);
  89. }
  90. }
  91. }
  92. }