it looks like you're no longer monitoring this thread, but for the benefit of anyone else reading it, we raised an MSDN incident on this and it has been confirmed as a problem, although it is not known when a fix will be available, or whether the fix, when it comes, will allow generic objects serialised without the fix to be deserialised by code with the fix. They also confirmed that the AssemblyResolve event was a valid workaround, and that it shouldn't have any adverse effects. They pointed out that the event only needs to be subscribed to once per app domain, as long as the program only has one app domain the subscription can be put in Main regardless how many assemblies or threads are doing serialisation.
However, it did become clear that the code in my previous post is quite wrong. This is how I think the event handler should look:
System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
// args.Name looks like this:
// "<AssemblyName>, Version=<major>.<minor>.<build>.<revison>, Culture=neutral, PublicKeyToken=<16 hexit number>"
// We need to parse it to extract the version number and the simple name
string versionStr = args.Name.Substring(args.Name.IndexOf("=") + 1); // Don't look for "Version" it may vary by locale
versionStr = versionStr.Substring(0, versionStr.IndexOf(","));
string simpleName = args.Name.Substring(0, args.Name.IndexOf(','));
// Load the assembly using just the name
AssemblyName assemblyName = new AssemblyName();
assemblyName.Name = simpleName;
Assembly assembly = Assembly.Load(assemblyName);
// Now replace the assembly's version number with the required version and return it.
assembly.GetName().Version = new Version(versionStr);
return assembly;
}