SerializationTestServices.cs 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. // -----------------------------------------------------------------------
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. // -----------------------------------------------------------------------
  4. #if !SILVERLIGHT
  5. using System;
  6. using System.IO;
  7. using System.Runtime.Serialization.Formatters.Binary;
  8. using System.Reflection;
  9. using Microsoft.VisualStudio.TestTools.UnitTesting;
  10. namespace System.Runtime.Serialization
  11. {
  12. public static class SerializationTestServices
  13. {
  14. /// <summary>
  15. /// Serializes and then deserializes the specified value.
  16. /// </summary>
  17. public static T RoundTrip<T>(T value)
  18. {
  19. Assert.IsNotNull(value);
  20. using (MemoryStream stream = new MemoryStream())
  21. {
  22. BinaryFormatter formatter = new BinaryFormatter();
  23. formatter.Serialize(stream, value);
  24. stream.Seek(0, SeekOrigin.Begin);
  25. return (T)formatter.Deserialize(stream);
  26. }
  27. }
  28. /// <summary>
  29. /// Creates an instance of a type using the serialization constructor.
  30. /// </summary>
  31. public static T Create<T>(SerializationInfo info, StreamingContext context)
  32. {
  33. ConstructorInfo constructor = typeof(T).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null,
  34. new Type[] { typeof(SerializationInfo), typeof(StreamingContext) },
  35. (ParameterModifier[])null);
  36. Assert.IsNotNull(constructor, "Type does not have a private or protected serialization constructor.");
  37. try
  38. {
  39. return (T)constructor.Invoke(new object[] { info, context });
  40. }
  41. catch (TargetInvocationException ex)
  42. {
  43. throw ex.InnerException;
  44. }
  45. }
  46. /// <summary>
  47. /// Returns a new instance of <see cref="SerializationInfo"/> replacing the specified member name with the specified value.
  48. /// </summary>
  49. public static SerializationInfo CreateSerializationInfoReplacingMember<T>(string memberName, object value)
  50. where T : ISerializable, new()
  51. {
  52. return CreateSerializationInfoReplacingMember(memberName, value, () => new T());
  53. }
  54. /// <summary>
  55. /// Returns a new instance of <see cref="SerializationInfo"/> replacing the specified member name with the specified value.
  56. /// </summary>
  57. public static SerializationInfo CreateSerializationInfoReplacingMember<T>(string memberName, object value, Func<T> creator)
  58. where T : ISerializable
  59. {
  60. T serializableObject = creator();
  61. var info = GetObjectDataFrom(serializableObject);
  62. return CloneReplacingMember<T>(info, memberName, value);
  63. }
  64. /// <summary>
  65. /// Returns a new instance of <see cref="SerializationInfo"/> removing the specified member name.
  66. /// </summary>
  67. public static SerializationInfo CreateSerializationInfoRemovingMember<T>(string memberName)
  68. where T : ISerializable, new()
  69. {
  70. return CreateSerializationInfoRemovingMember(memberName, () => new T());
  71. }
  72. /// <summary>
  73. /// Returns a new instance of <see cref="SerializationInfo"/> removing the specified member name.
  74. /// </summary>
  75. public static SerializationInfo CreateSerializationInfoRemovingMember<T>(string memberName, Func<T> creator)
  76. where T : ISerializable
  77. {
  78. T serializableObject = creator();
  79. var info = GetObjectDataFrom(serializableObject);
  80. return CloneRemovingMember<T>(info, memberName);
  81. }
  82. private static SerializationInfo CloneReplacingMember<T>(SerializationInfo info, string memberName, object value)
  83. {
  84. return Clone<T>(info, (entry, clone) =>
  85. {
  86. if (entry.Name != memberName)
  87. {
  88. return true;
  89. }
  90. // Replace the entry
  91. clone.AddValue(entry.Name, value, value == null ? entry.ObjectType : value.GetType());
  92. return false;
  93. });
  94. }
  95. private static SerializationInfo CloneRemovingMember<T>(SerializationInfo info, string memberName)
  96. {
  97. return Clone<T>(info, (entry, clone) =>
  98. {
  99. // Add everything except the member we want to remove
  100. return entry.Name != memberName;
  101. });
  102. }
  103. private static SerializationInfo Clone<T>(SerializationInfo info, Func<SerializationEntry, SerializationInfo, bool> predicate)
  104. {
  105. var clone = GetEmptySerializationInfo<T>();
  106. foreach (var entry in info)
  107. {
  108. if (predicate(entry, clone))
  109. {
  110. clone.AddValue(entry.Name, entry.Value, entry.ObjectType);
  111. }
  112. }
  113. return clone;
  114. }
  115. private static SerializationInfo GetObjectDataFrom<T>(T serializableObject) where T : ISerializable
  116. {
  117. var info = GetEmptySerializationInfo<T>();
  118. serializableObject.GetObjectData(info, new StreamingContext());
  119. return info;
  120. }
  121. private static SerializationInfo GetEmptySerializationInfo<T>()
  122. {
  123. StrictFormatterConverter converter = new StrictFormatterConverter();
  124. return new SerializationInfo(typeof(T), converter);
  125. }
  126. }
  127. }
  128. #endif // !SILVERLIGHT