// -----------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// -----------------------------------------------------------------------
#if !SILVERLIGHT
using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Reflection;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace System.Runtime.Serialization
{
public static class SerializationTestServices
{
///
/// Serializes and then deserializes the specified value.
///
public static T RoundTrip(T value)
{
Assert.IsNotNull(value);
using (MemoryStream stream = new MemoryStream())
{
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(stream, value);
stream.Seek(0, SeekOrigin.Begin);
return (T)formatter.Deserialize(stream);
}
}
///
/// Creates an instance of a type using the serialization constructor.
///
public static T Create(SerializationInfo info, StreamingContext context)
{
ConstructorInfo constructor = typeof(T).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null,
new Type[] { typeof(SerializationInfo), typeof(StreamingContext) },
(ParameterModifier[])null);
Assert.IsNotNull(constructor, "Type does not have a private or protected serialization constructor.");
try
{
return (T)constructor.Invoke(new object[] { info, context });
}
catch (TargetInvocationException ex)
{
throw ex.InnerException;
}
}
///
/// Returns a new instance of replacing the specified member name with the specified value.
///
public static SerializationInfo CreateSerializationInfoReplacingMember(string memberName, object value)
where T : ISerializable, new()
{
return CreateSerializationInfoReplacingMember(memberName, value, () => new T());
}
///
/// Returns a new instance of replacing the specified member name with the specified value.
///
public static SerializationInfo CreateSerializationInfoReplacingMember(string memberName, object value, Func creator)
where T : ISerializable
{
T serializableObject = creator();
var info = GetObjectDataFrom(serializableObject);
return CloneReplacingMember(info, memberName, value);
}
///
/// Returns a new instance of removing the specified member name.
///
public static SerializationInfo CreateSerializationInfoRemovingMember(string memberName)
where T : ISerializable, new()
{
return CreateSerializationInfoRemovingMember(memberName, () => new T());
}
///
/// Returns a new instance of removing the specified member name.
///
public static SerializationInfo CreateSerializationInfoRemovingMember(string memberName, Func creator)
where T : ISerializable
{
T serializableObject = creator();
var info = GetObjectDataFrom(serializableObject);
return CloneRemovingMember(info, memberName);
}
private static SerializationInfo CloneReplacingMember(SerializationInfo info, string memberName, object value)
{
return Clone(info, (entry, clone) =>
{
if (entry.Name != memberName)
{
return true;
}
// Replace the entry
clone.AddValue(entry.Name, value, value == null ? entry.ObjectType : value.GetType());
return false;
});
}
private static SerializationInfo CloneRemovingMember(SerializationInfo info, string memberName)
{
return Clone(info, (entry, clone) =>
{
// Add everything except the member we want to remove
return entry.Name != memberName;
});
}
private static SerializationInfo Clone(SerializationInfo info, Func predicate)
{
var clone = GetEmptySerializationInfo();
foreach (var entry in info)
{
if (predicate(entry, clone))
{
clone.AddValue(entry.Name, entry.Value, entry.ObjectType);
}
}
return clone;
}
private static SerializationInfo GetObjectDataFrom(T serializableObject) where T : ISerializable
{
var info = GetEmptySerializationInfo();
serializableObject.GetObjectData(info, new StreamingContext());
return info;
}
private static SerializationInfo GetEmptySerializationInfo()
{
StrictFormatterConverter converter = new StrictFormatterConverter();
return new SerializationInfo(typeof(T), converter);
}
}
}
#endif // !SILVERLIGHT