ReadOnlyDictionaryInterfaceImplementerSerializer.cs 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. /* Copyright 2018-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.Collections;
  17. using System.Collections.Generic;
  18. using System.Collections.ObjectModel;
  19. using System.Reflection;
  20. using MongoDB.Bson.Serialization.Options;
  21. namespace MongoDB.Bson.Serialization.Serializers
  22. {
  23. /// <summary>
  24. /// Represents a serializer for a class that implements <see cref="IDictionary{TKey, TValue}"/>.
  25. /// </summary>
  26. /// <typeparam name="TDictionary">The type of the dictionary.</typeparam>
  27. /// <typeparam name="TKey">The type of the key.</typeparam>
  28. /// <typeparam name="TValue">The type of the value.</typeparam>
  29. public class ReadOnlyDictionaryInterfaceImplementerSerializer<TDictionary, TKey, TValue> :
  30. DictionarySerializerBase<TDictionary, TKey, TValue>,
  31. IChildSerializerConfigurable,
  32. IDictionaryRepresentationConfigurable<ReadOnlyDictionaryInterfaceImplementerSerializer<TDictionary, TKey, TValue>>
  33. where TDictionary : class, IReadOnlyDictionary<TKey, TValue>
  34. {
  35. /// <summary>
  36. /// Initializes a new instance of the <see cref="ReadOnlyDictionaryInterfaceImplementerSerializer{TDictionary, TKey, TValue}"/> class.
  37. /// </summary>
  38. public ReadOnlyDictionaryInterfaceImplementerSerializer()
  39. {
  40. }
  41. /// <summary>
  42. /// Initializes a new instance of the <see cref="ReadOnlyDictionaryInterfaceImplementerSerializer{TDictionary, TKey, TValue}"/> class.
  43. /// </summary>
  44. /// <param name="dictionaryRepresentation">The dictionary representation.</param>
  45. public ReadOnlyDictionaryInterfaceImplementerSerializer(DictionaryRepresentation dictionaryRepresentation)
  46. : base(dictionaryRepresentation)
  47. {
  48. }
  49. /// <summary>
  50. /// Initializes a new instance of the <see cref="ReadOnlyDictionaryInterfaceImplementerSerializer{TDictionary, TKey, TValue}"/> class.
  51. /// </summary>
  52. /// <param name="dictionaryRepresentation">The dictionary representation.</param>
  53. /// <param name="keySerializer">The key serializer.</param>
  54. /// <param name="valueSerializer">The value serializer.</param>
  55. public ReadOnlyDictionaryInterfaceImplementerSerializer(DictionaryRepresentation dictionaryRepresentation, IBsonSerializer<TKey> keySerializer, IBsonSerializer<TValue> valueSerializer)
  56. : base(dictionaryRepresentation, keySerializer, valueSerializer)
  57. {
  58. }
  59. // public methods
  60. /// <summary>
  61. /// Returns a serializer that has been reconfigured with the specified dictionary representation.
  62. /// </summary>
  63. /// <param name="dictionaryRepresentation">The dictionary representation.</param>
  64. /// <returns>The reconfigured serializer.</returns>
  65. public ReadOnlyDictionaryInterfaceImplementerSerializer<TDictionary, TKey, TValue> WithDictionaryRepresentation(DictionaryRepresentation dictionaryRepresentation)
  66. {
  67. return dictionaryRepresentation == DictionaryRepresentation
  68. ? this
  69. : new ReadOnlyDictionaryInterfaceImplementerSerializer<TDictionary, TKey, TValue>(dictionaryRepresentation, KeySerializer, ValueSerializer);
  70. }
  71. /// <summary>
  72. /// Returns a serializer that has been reconfigured with the specified dictionary representation and key value serializers.
  73. /// </summary>
  74. /// <param name="dictionaryRepresentation">The dictionary representation.</param>
  75. /// <param name="keySerializer">The key serializer.</param>
  76. /// <param name="valueSerializer">The value serializer.</param>
  77. /// <returns>The reconfigured serializer.</returns>
  78. public ReadOnlyDictionaryInterfaceImplementerSerializer<TDictionary, TKey, TValue> WithDictionaryRepresentation(DictionaryRepresentation dictionaryRepresentation, IBsonSerializer<TKey> keySerializer, IBsonSerializer<TValue> valueSerializer)
  79. {
  80. return dictionaryRepresentation == DictionaryRepresentation && keySerializer == KeySerializer && valueSerializer == ValueSerializer
  81. ? this
  82. : new ReadOnlyDictionaryInterfaceImplementerSerializer<TDictionary, TKey, TValue>(dictionaryRepresentation, keySerializer, valueSerializer);
  83. }
  84. /// <summary>
  85. /// Returns a serializer that has been reconfigured with the specified key serializer.
  86. /// </summary>
  87. /// <param name="keySerializer">The key serializer.</param>
  88. /// <returns>The reconfigured serializer.</returns>
  89. public ReadOnlyDictionaryInterfaceImplementerSerializer<TDictionary, TKey, TValue> WithKeySerializer(IBsonSerializer<TKey> keySerializer)
  90. {
  91. return keySerializer == KeySerializer
  92. ? this
  93. : new ReadOnlyDictionaryInterfaceImplementerSerializer<TDictionary, TKey, TValue>(DictionaryRepresentation, keySerializer, ValueSerializer);
  94. }
  95. /// <summary>
  96. /// Returns a serializer that has been reconfigured with the specified value serializer.
  97. /// </summary>
  98. /// <param name="valueSerializer">The value serializer.</param>
  99. /// <returns>The reconfigured serializer.</returns>
  100. public ReadOnlyDictionaryInterfaceImplementerSerializer<TDictionary, TKey, TValue> WithValueSerializer(IBsonSerializer<TValue> valueSerializer)
  101. {
  102. return valueSerializer == ValueSerializer
  103. ? this
  104. : new ReadOnlyDictionaryInterfaceImplementerSerializer<TDictionary, TKey, TValue>(DictionaryRepresentation, KeySerializer, valueSerializer);
  105. }
  106. // explicit interface implementations
  107. IBsonSerializer IChildSerializerConfigurable.ChildSerializer => ValueSerializer;
  108. IBsonSerializer IChildSerializerConfigurable.WithChildSerializer(IBsonSerializer childSerializer)
  109. {
  110. return WithValueSerializer((IBsonSerializer<TValue>)childSerializer);
  111. }
  112. IBsonSerializer IDictionaryRepresentationConfigurable.WithDictionaryRepresentation(DictionaryRepresentation dictionaryRepresentation)
  113. {
  114. return WithDictionaryRepresentation(dictionaryRepresentation);
  115. }
  116. /// <inheritdoc/>
  117. protected override ICollection<KeyValuePair<TKey, TValue>> CreateAccumulator()
  118. {
  119. return new Dictionary<TKey, TValue>();
  120. }
  121. /// <inheritdoc/>
  122. protected override TDictionary FinalizeAccumulator(ICollection<KeyValuePair<TKey, TValue>> accumulator)
  123. {
  124. try
  125. {
  126. return (TDictionary) Activator.CreateInstance(typeof(TDictionary), new object[] {accumulator});
  127. }
  128. catch (MissingMethodException exception)
  129. {
  130. throw new MissingMethodException(
  131. $"No suitable constructor found for IReadOnlyDictionary type: '{typeof(TDictionary).FullName}'.",
  132. exception);
  133. }
  134. }
  135. }
  136. }